Ansible conditional statement based on other roles?

6,589

Solution 1

Actually we have role_names variable in Ansible since late 2013. Confirmed with Ansible 1.9.2. So you can simply write a conditional like this:

when: "'package-postfix' not in role_names"

Solution 2

It can be done with following(quotation from documentation on ansible.com):

Additionally, group_names is a list (array) of all the groups the current host is in. This can be used in templates using Jinja2 syntax to make template source files that vary based on the group membership (or role) of the host:

{% if 'package-postfix' not in group_names %}
   # some part of a configuration file that only applies to not package-postfix
{% endif %}

Okay, based on you update: I would convert this to group definition, because role is related to group and it's more logical. You should create group which consists of group mx, mail, and host luna, then use suggested thing. Or you can define specific host_vars/group_vars which would say true or false.

For example: use group_vars: mx will contain: use_postfix: "False"

group_vars for mail will contain use_postfix: "False"

and host_var for luna will contain host_vars use_postfix: "False"

then you just do

when use_postifx != "False"

Sorry for english, i hope i made myself clear.

Share:
6,589

Related videos on Youtube

Joshua Boniface
Author by

Joshua Boniface

Updated on September 18, 2022

Comments

  • Joshua Boniface
    Joshua Boniface over 1 year

    I've got the following scenario with an Ansible deployment:

    • hostX has the role common-mta and a few other roles
    • hostY has the role common-mta as well as the role package-postfix

    The common-mta role copies a file (if you could have guessed, it's /etc/postfix/main.cf), but I want to restrict this based on whether a host has the role of package-postfix, rather than just restricting by hostname like I have now, e.g.:

    when: not group_names == "mail"
    

    What I'd like is something like:

    when: not role_names == "package-postfix"
    

    I think this would be much cleaner and allows me to arbitrarily add the package-postfix role to other hosts without having to modify the common-mta role at all.

    Is this possible?

    Edit: Navern's suggestion does not work for this particular use case; the list of roles is independent from the list of groups, and while I can do this via group, it's dirtier. Consider this, which is my actual task line:

    - name: install postfix generic config if we aren't an mx, mail, or luna host
      template: src=main.cf.j2 dest=/etc/postfix/main.cf
      when: "'luna' not in group_names and 'mx' not in group_names and 'mail' not in group_names"
    

    I'd like to replace this with:

    - name: install postfix generic config if we don't have the postfix role
      template: src=main.cf.j2 dest=/etc/postfix/main.cf
      when: "'package-postfix' not in role_names"
    

    However, role_names is not a valid variable, and so far in the documentation I can't find a variable which contains the list of roles the host is in, and not its groups. These may seem like the same thing, but in my case they're not, since the three groups I mention all share the package-postfix role. Hopefully that makes sense and I'm using Ansible correctly.

  • Joshua Boniface
    Joshua Boniface over 8 years
    Doesn't do what I want, see the edit I made to the OP.
  • Navern
    Navern over 8 years
    @JoshuaBoniface i have edited my answer accordingly:)
  • Joshua Boniface
    Joshua Boniface over 8 years
    I'm running 1.7.2 in Debian Stable so that explains it. Thanks for clarifying!
  • Joshua Boniface
    Joshua Boniface over 6 years
    So this ended up being technically right, but doesn't work with how I have things set up. I'm using a tree of includes for some roles (common stuff) to avoid putting it directly in the group definitions, since some of those are serial and I don't want to run all the common tasks one-host-at-a-time, but rather all together at once. Which means that while my "common" role is running, role_names only shows the "common" role and not the others that the particular host group belongs to. I guess I can't have my cake (simultaneous common part) and eat it too (get meaningful role_names values).
  • Joshua Boniface
    Joshua Boniface over 6 years
    And to clarify my structure: 1. site.yml: include common.yml, include host-notmail.yml, include host-mail.yml 2. common.yml: role 'common' 3. host-notmail.yml: role 'package-something' 4. host-mail.yml: role 'package-postfix'; while common.yml is running the group vars will (quite obviously too) not include the package-blah roles in role_names.