{"id":1208,"date":"2026-05-20T09:01:21","date_gmt":"2026-05-20T09:01:21","guid":{"rendered":"https:\/\/techno.slomka.biz\/?p=1208"},"modified":"2026-05-20T09:11:43","modified_gmt":"2026-05-20T09:11:43","slug":"mastering-dynamic-task-includes-in-ansible","status":"publish","type":"post","link":"https:\/\/techno.slomka.biz\/?p=1208","title":{"rendered":"Mastering Dynamic Task Includes in Ansible"},"content":{"rendered":"\n<p>One of the best ways (and easy) to keep your Ansible playbooks clean, modular, and DRY (Don&#8217;t Repeat Yourself) is by using dynamic task includes. Instead of writing massive, conditional playbooks with dozens of <code>when<\/code> statements, you can let your data drive your execution.<\/p>\n\n\n\n<p>The core idea is beautifully simple:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#EEFFFF;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#304047;color:#d5ffff\">YAML<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#EEFFFF;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>- name: Execute dynamically targeted action\n  ansible.builtin.include_tasks: \"{{ action }}.yml\"<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki material-theme\" style=\"background-color: #263238\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #89DDFF\">-<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #F07178\">name<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #C3E88D\">Execute dynamically targeted action<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">  <\/span><span style=\"color: #F07178\">ansible.builtin.include_tasks<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">{{ action }}.yml<\/span><span style=\"color: #89DDFF\">&quot;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Depending on the value of the <code>action <\/code>variable (e.g., <code>install<\/code>, <code>configure<\/code>, or <code>backup<\/code>), Ansible will look for and execute <code>install.yml<\/code>, <code>configure.yml<\/code>, or <code>backup.yml<\/code> on the fly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why Use This Pattern?<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Cleaner Codebase:<\/strong> Instead of one massive <code>main.yml<\/code> packed with tasks, you break your logic into small, focused files.<\/li>\n\n\n\n<li><strong>Role Extensibility:<\/strong> You can create &#8220;plugin-style&#8221; architectures. Want to support a new operating system or application action? Just drop a new <code>.yml<\/code> file into the tasks directory.<\/li>\n\n\n\n<li><strong>Reduced Conditional Noise:<\/strong> You completely avoid appending <code>when: action == 'install'<\/code> to fifteen different tasks.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">\u26a0\ufe0f The Gotchas (What to Watch Out For)<\/h2>\n\n\n\n<p>While highly effective, <code>include_tasks<\/code> is evaluated at <strong>runtime<\/strong>, which introduces a couple of architectural quirks you need to design around.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. The Missing File Trap<\/h3>\n\n\n\n<p>If <code>action<\/code> is set to <code>restore<\/code>, but <code>restore.yml<\/code> doesn&#8217;t exist, Ansible will fail mid-playbook execution.<\/p>\n\n\n\n<p><strong>The Fix:<\/strong> Use Ansible&#8217;s <code>query<\/code> with the <code>first_found<\/code> plugin to handle fallbacks or graceful skips.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#EEFFFF;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#304047;color:#d5ffff\">YAML<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#EEFFFF;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>- name: Include action tasks safely\n  ansible.builtin.include_tasks: \"{{ item }}\"\n  with_first_found:\n    - files:\n        - \"{{ action }}.yml\"\n        - \"default_action.yml\" # Fallback file\n      skip: true # Or skip entirely if neither exists<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki material-theme\" style=\"background-color: #263238\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #89DDFF\">-<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #F07178\">name<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #C3E88D\">Include action tasks safely<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">  <\/span><span style=\"color: #F07178\">ansible.builtin.include_tasks<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">{{ item }}<\/span><span style=\"color: #89DDFF\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">  <\/span><span style=\"color: #F07178\">with_first_found<\/span><span style=\"color: #89DDFF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">    <\/span><span style=\"color: #89DDFF\">-<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #F07178\">files<\/span><span style=\"color: #89DDFF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #89DDFF\">-<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">{{ action }}.yml<\/span><span style=\"color: #89DDFF\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #89DDFF\">-<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">default_action.yml<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #546E7A; font-style: italic\"># Fallback file<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">      <\/span><span style=\"color: #F07178\">skip<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #FF9CAC\">true<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #546E7A; font-style: italic\"># Or skip entirely if neither exists<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Please see my follow-up post <a href=\"https:\/\/techno.slomka.biz\/?p=1212\">Deep Dive Missing File Trap<\/a>. &#8220;Dynamic task includes&#8221; is a classic, incredibly powerful Ansible pattern\u2014but it&#8217;s also one that comes with a few hidden gotchas that can absolutely ruin a deployment if you aren&#8217;t prepared for them.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. Handlers and Tags Limitations<\/h3>\n\n\n\n<p class=\"has-black-color has-text-color has-link-color wp-elements-5870270f782b796fef19d0d2f76cf219\">Because <strong>dynamic includes aren&#8217;t parsed until the play actually reaches that task<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You cannot easily trigger handlers defined <em>inside<\/em> a dynamically included file from outside of it.<\/li>\n\n\n\n<li>Running a playbook with <code>--tags<\/code> might skip your <code>include_tasks<\/code> entirely unless the include task itself carries the tag.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">A Real-World Example: Multi-OS Configurations<\/h2>\n\n\n\n<p>A stellar use case for this is handling OS-specific setup without cluttering your main tasks file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>tasks\/main.yml<\/code><\/h3>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#EEFFFF;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#304047;color:#d5ffff\">YAML<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#EEFFFF;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>- name: Load OS-specific configuration tasks\n  ansible.builtin.include_tasks: \"{{ ansible_facts&#91;'os_family'&#93; | lower }}.yml\"<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki material-theme\" style=\"background-color: #263238\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #89DDFF\">-<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #F07178\">name<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #C3E88D\">Load OS-specific configuration tasks<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">  <\/span><span style=\"color: #F07178\">ansible.builtin.include_tasks<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">{{ ansible_facts&#91;&#39;os_family&#39;&#93; | lower }}.yml<\/span><span style=\"color: #89DDFF\">&quot;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><code>tasks\/debian.yml<\/code><\/h3>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#EEFFFF;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#304047;color:#d5ffff\">YAML<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#EEFFFF;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>- name: Install Debian\/Ubuntu packages\n  ansible.builtin.apt:\n    name: Apache2\n    state: present<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki material-theme\" style=\"background-color: #263238\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #89DDFF\">-<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #F07178\">name<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #C3E88D\">Install Debian\/Ubuntu packages<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">  <\/span><span style=\"color: #F07178\">ansible.builtin.apt<\/span><span style=\"color: #89DDFF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">    <\/span><span style=\"color: #F07178\">name<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #C3E88D\">Apache2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">    <\/span><span style=\"color: #F07178\">state<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #C3E88D\">present<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><code>tasks\/redhat.yml<\/code><\/h3>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#EEFFFF;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#304047;color:#d5ffff\">YAML<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#EEFFFF;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>- name: Install RedHat\/CentOS packages\n  ansible.builtin.yum:\n    name: httpd\n    state: present<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki material-theme\" style=\"background-color: #263238\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #89DDFF\">-<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #F07178\">name<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #C3E88D\">Install RedHat\/CentOS packages<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">  <\/span><span style=\"color: #F07178\">ansible.builtin.yum<\/span><span style=\"color: #89DDFF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">    <\/span><span style=\"color: #F07178\">name<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #C3E88D\">httpd<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">    <\/span><span style=\"color: #F07178\">state<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #C3E88D\">present<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-verse\"><strong>Quick Tip on Syntax:<\/strong> Notice the underscore in <code>include_tasks<\/code>. Older versions of Ansible allowed dashes (<code>include-tasks<\/code>), but modern Ansible strictly standardizes on underscores (<code>include_tasks<\/code>). Always use underscores to ensure your playbooks are future-proof!<\/pre>\n<\/blockquote>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the best ways (and easy) to keep your Ansible playbooks clean, modular, and DRY (Don&#8217;t Repeat Yourself) is by using dynamic task includes. Instead of writing massive, conditional playbooks with dozens of when statements, you can let your data drive your execution. The core idea is beautifully simple: Depending on the value of the action variable (e.g., install, configure, or backup), Ansible will look for and execute install.yml, configure.yml, or backup.yml on the fly. Why Use This Pattern? \u26a0\ufe0f The Gotchas (What to Watch Out For) While highly effective, include_tasks is evaluated at runtime, which introduces a couple of architectural quirks you need to design around. 1. The Missing File Trap If action is set to restore, but restore.yml doesn&#8217;t exist, Ansible will fail mid-playbook execution. The Fix: Use Ansible&#8217;s query with the first_found plugin to handle fallbacks or graceful skips. Please see my follow-up post Deep Dive Missing File Trap. &#8220;Dynamic task includes&#8221; is a classic, incredibly powerful Ansible pattern\u2014but it&#8217;s also one that comes with a few hidden gotchas that can absolutely ruin a deployment if you aren&#8217;t prepared for them. 2. Handlers and Tags Limitations Because dynamic includes aren&#8217;t parsed until the play actually reaches that task: A Real-World Example: Multi-OS Configurations A stellar use case for this is handling OS-specific setup without cluttering your main tasks file. tasks\/main.yml tasks\/debian.yml tasks\/redhat.yml Quick Tip on Syntax: Notice the underscore in include_tasks. Older versions of Ansible allowed dashes (include-tasks), but modern Ansible strictly standardizes on underscores (include_tasks). Always use underscores to ensure your playbooks are future-proof!<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[30,8],"tags":[40],"class_list":["post-1208","post","type-post","status-publish","format-standard","hentry","category-ansible","category-konzepte","tag-ansible"],"_links":{"self":[{"href":"https:\/\/techno.slomka.biz\/index.php?rest_route=\/wp\/v2\/posts\/1208","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/techno.slomka.biz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/techno.slomka.biz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/techno.slomka.biz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/techno.slomka.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1208"}],"version-history":[{"count":4,"href":"https:\/\/techno.slomka.biz\/index.php?rest_route=\/wp\/v2\/posts\/1208\/revisions"}],"predecessor-version":[{"id":1215,"href":"https:\/\/techno.slomka.biz\/index.php?rest_route=\/wp\/v2\/posts\/1208\/revisions\/1215"}],"wp:attachment":[{"href":"https:\/\/techno.slomka.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1208"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/techno.slomka.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1208"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/techno.slomka.biz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1208"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}