Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Role dependencies across multiple plays

594 views
Skip to first unread message

Jürgen Haas

unread,
Dec 5, 2013, 10:40:28 AM12/5/13
to ansible...@googlegroups.com
According to the documentation, role dependencies would no longer run more than once, unless the setting allow_duplicates: yes was used. I assume that is if a role is included more than once with the same play.

In my scenario a role called common is included from almost every other role and hence gets executed every time which makes the whole thing pretty lengthy. Is there a way to stop this from happening?

The main playbook looks more or less like this:

- name: "Apache Servers"
  roles:
    - apache

- name: "MySQL Servers"
  roles:
    - mysql

- name: "Some other Servers"
  roles:
    - something

All the roles (apache, mysql, something) are dependent on the role common and if one of my hosts has more than one role, then both roles get executed and therefore common gets executed more than once. Can I change this?

Nathan Howell

unread,
Dec 5, 2013, 4:52:21 PM12/5/13
to ansible...@googlegroups.com
I ended up having my common role use set_fact on its first run, then it gets skipped on subsequent runs based on that fact, but it's not an ideal solution. I'd be interested in a better answer for this as well.

Nathan

James Cammarata

unread,
Dec 5, 2013, 5:31:39 PM12/5/13
to ansible...@googlegroups.com
Jürgen, the allow_duplicates setting, along with all role data, is per-play. Whether it was included or not is tracked in the play itself, not per-host, so getting that information to persist across plays within a playbook would be tricky when each play included different host lists.

Nathan's solution is probably the best work-around for this, which you could also do by registering a variable as the last task in the common role.


--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--

James Cammarata <jcamm...@ansibleworks.com>
Sr. Software Engineer, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Michael DeHaan

unread,
Dec 5, 2013, 5:34:50 PM12/5/13
to ansible...@googlegroups.com
Yeah so what Nathan's said is this:

- hosts: all
  roles:
    - common

- hosts: other
  roles:
    - foo

- hosts: more
  roles:
    - bar
    - baz

And if you want to just run hosts in the group "more", you can do that with "--limit more"


Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Jürgen Haas

unread,
Dec 6, 2013, 2:51:34 AM12/6/13
to ansible...@googlegroups.com
Very nice approach. FWIW here is how I've been doing it and it works, thanks to Nathan.

/roles/common/tasks/main.yml (at the very end):
- name: 'Common | Remember that this role had been run'
  set_fact: role_common_completed=true

/roles/OTHERS/meta/main.yml
dependencies:
  - { role: common, when: role_common_completed is not defined }

Perfect !

Nathan Howell

unread,
Dec 6, 2013, 3:04:17 AM12/6/13
to ansible...@googlegroups.com
Here's a little further improvement that I have, so that I don't need the condition on the role dependency. I move all the common role tasks to roles/common/tasks/common.yml, and then my roles/common/tasks/main.yml is just this:

---
- include: common.yml
  when: common_has_run is not defined

- set_fact: common_has_run=true
  when: common_has_run is not defined

That way, I can depend on the common role from anywhere, without having to specify the condition every time.

Nathan
Reply all
Reply to author
Forward
0 new messages