# Dynamic 'include:' lines?

**URL:** <https://forum.ansible.com/t/dynamic-include-lines/13709>\
**Category:** Ansible Project\
**Created:** [October 17, 2013, 5:25pm UTC](https://forum.ansible.com/t/dynamic-include-lines/13709 "2013-10-17T17:25:25Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Brian\_Candler](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@Brian\_Candler](https://forum.ansible.com/u/Brian_Candler)\
**Post date:** [October 17, 2013, 5:25pm UTC](https://forum.ansible.com/t/dynamic-include-lines/13709/1 "2013-10-17T17:25:25Z")

</div>

Using ansible 1.3.3, I am trying to structure my tasks like this:

==\> roles/ntp\_client/tasks/main.yml \<==

- include: “{{ ansible\_os\_family }}.yml”

==\> roles/ntp\_client/tasks/Debian.yml \<==

- action: apt pkg=ntp state=installed
- service: name=ntp state=started enabled=yes

==\> roles/ntp\_client/tasks/RedHat.yml \<==

- yum: name=ntp state=installed
- service: name=ntpd state=started enabled=yes

It fails with:

ERROR: file not found: /root/ansible/roles/ntp\_client/tasks/{{ansible\_os\_family}}.yml

I also tried:

- include: $ansible\_os\_family

- include: ${ansible\_os\_family}.yml

which give:

ERROR: file not found: /root/ansible/roles/ntp\_client/tasks/$ansible\_os\_family

ERROR: file not found: /root/ansible/roles/ntp\_client/tasks/${ansible\_os\_family}.yml

respectively.

What I am trying to avoid is this:

- include: Debian.yml  
when: ansible\_os\_family == ‘Debian’
- include: RedHat.yml  
when: ansible\_os\_family == ‘RedHat’

which works, but is tedious if I have to write it for every role, and it also gives lots of ‘skipping’ tasks when run.

There is a tiny note at [http://www.ansibleworks.com/docs/playbooks\_roles.html](http://www.ansibleworks.com/docs/playbooks_roles.html) which says:  
“Note that you cannot do variable substitution when including one playbook inside another.”  
which maybe applies to tasks/roles too - this isn’t clear to me.

I could of course define distinct roles called, say:

roles/ntp\_client\_Debian  
roles/ntp\_client\_RedHat

but to avoid conditionally including them, I would have to make different playbooks for Debian-based hosts and RedHat-based hosts.

Any other suggestions for how to achieve what I want here?

Thanks,

Brian.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [October 17, 2013, 5:39pm UTC](https://forum.ansible.com/t/dynamic-include-lines/13709/2 "2013-10-17T17:39:45Z")

</div>

Dynamic includes are not a thing.

Why? Task objects must be applied to each host in a group set.

This:

- include: Debian.yml  
when: ansible\_os\_family == ‘Debian’
- include: RedHat.yml  
when: ansible\_os\_family == ‘RedHat’

is ok.

This is better: [http://www.ansibleworks.com/docs/playbooks\_best\_practices.html#operating-system-and-distribution-variance](http://www.ansibleworks.com/docs/playbooks_best_practices.html#operating-system-and-distribution-variance)

---

<div class="post-metadata">

**Author:** ![Brian\_Candler](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@Brian\_Candler](https://forum.ansible.com/u/Brian_Candler)\
**Post date:** [October 17, 2013, 5:53pm UTC](https://forum.ansible.com/t/dynamic-include-lines/13709/3 "2013-10-17T17:53:03Z")

</div>

OK, I found  
[http://www.ansibleworks.com/docs/playbooks\_conditionals.html#applying-when-to-roles-and-includes](http://www.ansibleworks.com/docs/playbooks_conditionals.html#applying-when-to-roles-and-includes)

“You will note a lot of ‘skipped’ output by default in Ansible when using this approach on systems that don’t match the criteria. Read up on the ‘group\_by’ module in the docs for a more streamlined way to accomplish the same thing.”

So I guess this means I can write a playbook like

- hosts: all  
group\_by: key=family\_{{ansible\_os\_family}}
- hosts: family\_RedHat  
roles: ntp\_client\_redhat
- hosts: family\_Debian  
roles: ntp\_client\_debian

I also found this:  
[http://www.ansibleworks.com/docs/playbooks\_conditionals.html#conditional-imports](http://www.ansibleworks.com/docs/playbooks_conditionals.html#conditional-imports)

So, I can abstract the name of the package into a variable (i.e. “ntp” or “ntpd” depending on the os\_family); but I don’t think I can abstract out whether to call the “apt” or “yum” module. Or can I?

Thanks,

Brian.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [October 17, 2013, 6:00pm UTC](https://forum.ansible.com/t/dynamic-include-lines/13709/4 "2013-10-17T18:00:43Z")

</div>

You don’t want to abstract out the name of the apt or yum module.

Not only are the package names are always different, they have different capabilities, as we chose to not do the minimal implementation for each.

In fact, many things are also different from OS to OS – think about how apache is managed so very differently between Ubuntu and Red Hat Enterprise Linux, for instance.

But you really should use group\_by, it is your friend 🙂

---

<div class="post-metadata">

**Author:** ![Brian\_Candler](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@Brian\_Candler](https://forum.ansible.com/u/Brian_Candler)\
**Post date:** [October 17, 2013, 7:37pm UTC](https://forum.ansible.com/t/dynamic-include-lines/13709/5 "2013-10-17T19:37:51Z")

</div>

> But you really should use group\_by, it is your friend 🙂

Thank you. So here’s what my new friend looks like, in a playbook:

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [October 17, 2013, 8:39pm UTC](https://forum.ansible.com/t/dynamic-include-lines/13709/6 "2013-10-17T20:39:43Z")

</div>

Group by did in fact change the definition of the host temporarily as it ran, but I understand what you are saying.

Can anyone think of a reason why someone would attach a handler to a group\_by ?

---

<div class="post-metadata">

**Author:** ![Brice\_Burgess](https://avatars.discourse-cdn.com/v4/letter/b/d2c977/32.png) [@Brice\_Burgess](https://forum.ansible.com/u/Brice_Burgess)\
**Post date:** [October 17, 2013, 10:35pm UTC](https://forum.ansible.com/t/dynamic-include-lines/13709/7 "2013-10-17T22:35:16Z")

</div>

Is variable substitution being removed from include lines?

E.g.

- { include: “{{ common\_tasks\_path}}/deploy\_tasks.yml” }

This behavior used to work && will break a lot of our existing playbooks.

Thanks,

~ Brice

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [October 17, 2013, 10:38pm UTC](https://forum.ansible.com/t/dynamic-include-lines/13709/8 "2013-10-17T22:38:46Z")

</div>

if you pass stuff in with “-e” here it will work fine.

You never could use inventory variables here.

---

<div class="post-metadata">

**Author:** ![Brice\_Burgess](https://avatars.discourse-cdn.com/v4/letter/b/d2c977/32.png) [@Brice\_Burgess](https://forum.ansible.com/u/Brice_Burgess)\
**Post date:** [October 17, 2013, 11:13pm UTC](https://forum.ansible.com/t/dynamic-include-lines/13709/9 "2013-10-17T23:13:22Z")

</div>

OK. It also worked with vars\_files from the base playbook well enough for us in the past && the convenience of defining paths / and re-using common task files is very nice.

It makes sense to force a consistent set of tasks per host group. Will keep this in mind as we refactor.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [October 17, 2013, 11:32pm UTC](https://forum.ansible.com/t/dynamic-include-lines/13709/10 "2013-10-17T23:32:11Z")

</div>

vars\_files that do not depend on facts are essentially global and fine there, yes.

---

<div class="post-metadata">

**Author:** ![Brian\_Candler](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@Brian\_Candler](https://forum.ansible.com/u/Brian_Candler)\
**Post date:** [October 18, 2013, 8:39am UTC](https://forum.ansible.com/t/dynamic-include-lines/13709/11 "2013-10-18T08:39:58Z")

</div>

> Can anyone think of a reason why someone would attach a handler to a group\_by ?

To side-step this question, couldn’t you just check for the presence of a “notify” clause?

group\_by without notify =\> ok  
group\_by with notify =\> changed

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [October 18, 2013, 12:46pm UTC](https://forum.ansible.com/t/dynamic-include-lines/13709/12 "2013-10-18T12:46:44Z")

</div>

I generally don’t like to special case code in the main program like that.

Plus, I’m more interested in the original question 🙂

---

<div class="post-metadata">

**Author:** ![David\_Karban](https://avatars.discourse-cdn.com/v4/letter/d/90db22/32.png) [@David\_Karban](https://forum.ansible.com/u/David_Karban)\
**Post date:** [October 18, 2013, 1:32pm UTC](https://forum.ansible.com/t/dynamic-include-lines/13709/13 "2013-10-18T13:32:58Z")

</div>

I personally add changed\_when: false.

Personally I haven`t thougth about notyfiing it yet.

---

<div class="post-metadata">

**Author:** ![Mailo\_Svetel](https://avatars.discourse-cdn.com/v4/letter/m/ea5d25/32.png) [@Mailo\_Svetel](https://forum.ansible.com/u/Mailo_Svetel)\
**Post date:** [February 17, 2016, 10:34pm UTC](https://forum.ansible.com/t/dynamic-include-lines/13709/14 "2016-02-17T22:34:57Z")

</div>

On Ansible 2.0.0.2 I am able to do this:

`

- include: “{{ansible\_os\_family | lower}}.yml”  
`

Dne čtvrtek 17. října 2013 19:25:25 UTC+2 candlerb napsal(a):
