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:
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 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.
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
OK, I found
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
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.
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
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:
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 ?
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
if you pass stuff in with “-e” here it will work fine.
You never could use inventory variables here.
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.
vars_files that do not depend on facts are essentially global and fine there, yes.
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
I generally don’t like to special case code in the main program like that.
Plus, I’m more interested in the original question
I personally add changed_when: false.
Personally I haven`t thougth about notyfiing it yet.
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):