Role dependencies across multiple plays

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?

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

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.

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”

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 !

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: