When to use role dependencies?

I’m trying to figure out when and how best to use role dependencies.

Currently I have a single role for handling my Postfix configuration on ALL my hosts; some are classified as ‘mail-servers’ and the rest as ‘mail-clients’. Depending upon a role variable (‘mailserver_class’) I can set when I call the role, I ether get one set of Postfix configuration files or the other.

My site-role.yml currently looks like this:

  • hosts: all:!mail-servers
    roles:

  • { role: postfix, tags: [mail-client] }

  • hosts: mail-servers
    roles:

  • { role: postfix, tags: [mail-server], mailserver_class: server }

This works for me. however, I can see accomplishing basically the same thing by creating ‘mail-client’ and ‘mail-server’ roles that both call ‘postfix’ as a role dependency, such as:

site-role.yml:

-hosts: all:!mail-servers
roles:

  • mail-client

-hosts: mail-servers
roles:

  • mail-servers

roles/mail-server/meta/main.yml:

dependencies:
  - { role: postfix }

roles/mail-server/meta/main.yml:

dependencies:
  - { role: postfix, mailserver_class: server }

To me, it seems that setting up actual ‘mail-client’ and ‘mail-server’ roles each with a dependency on the ‘postfix’ role is more work and I’m not sure I really gain anything in this case. On the other hand, by defining these two roles, I can probably have my different Postfix configuration templates live under those roles and probably not need the ‘mailserver_class’ variable. [To be perfectly honest, my gut instinct is to have everything in the Postfix role and then have internal logic determine which config file to use - separating the configs to different role just feel very, very wrong to me.]

So, what thoughts do you have on these layouts? It feels like I can accomplish the same thing with either layout. I wanted to see what other people thought about these two cases and what advantages or disadvantages each layout offered. Your thoughts are appreciated.

thx
Chris.

The main advantage I see to doing it with the role deps is that you can specify the mailserver_class parameter there. That means you don’t have to remember to do it when you include the role, which is a mistake a new admin in your environment might make. Beyond that, these two functions are similar enough that, as you point out, there’s not much of a win in refactoring them.

Role deps are definitely more suited to interconnected but non-related things, for instance a drupal stack where you’re installing nginx, memcached, and php resulting in a clear chain of dependencies.

I started by handling this problem using conditionals but have since switched to distinct client and server roles (e.g., email-client, email-server, ntp-client, ntp-server, etc. ). In fact I have moved even further in that direction to using small roles for every major subsystem as well (iptables, ssh, aide, etc.). This modular, many roles approach has worked better for me. Now they can evolve at different rates and so on. Separating roles makes them explicit so now my site.yml reads like documentation, showing all the subsystems used by a given host.

In the future I think a highly modular approach will also be more Ansible Galaxy friendly. Modular roles will be easier to swap out for better quality community one from Galaxy.

–Aaron