# Setting vars conditionally within a \*role\*

**URL:** <https://forum.ansible.com/t/setting-vars-conditionally-within-a-role/13728>\
**Category:** Ansible Project\
**Created:** [October 21, 2013, 1:23pm UTC](https://forum.ansible.com/t/setting-vars-conditionally-within-a-role/13728 "2013-10-21T13:23:16Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Brian\_Candler](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@Brian\_Candler](https://forum.ansible.com/u/Brian_Candler)\
**Post date:** [October 21, 2013, 1:23pm UTC](https://forum.ansible.com/t/setting-vars-conditionally-within-a-role/13728/1 "2013-10-21T13:23:16Z")

</div>

The manual has examples on setting variables conditionally within a _playbook_. e.g.

```auto
- hosts: all
  remote_user: root
  vars_files:
    - "vars/common.yml"
    - ["vars/{{ ansible_os_family }}.yml", "vars/os_defaults.yml"]
  tasks:
  - name: make sure apache is running
    service: name={{ apache }} state=running

```

My question is how to do this within a _role_. Specific case:

action: copy src={{item}} dest=/{{item}} mode=750 group={{snmp\_group}}

I want to set snmp\_group to “wheel” when ansible\_os\_family==‘RedHat’, and “snmp” when ansible\_os\_family==‘Debian’. This logic definitely belongs in the role, not in any playbook which wraps it.

At the moment all I can think of is some Jinja2 conditional buried directly into the assignment:

snmp\_group: “{% if ansible\_os\_family==‘RedHat’ %}wheel{% else %}snmp{% endif %}”

This seems to work, but it’s pretty ugly. I can’t see how to do anything equivalent to vars\_files in a role, or indeed how to include anything under vars/ except vars/main.yml

What am I missing?

Thanks,

Brian.

---

<div class="post-metadata">

**Author:** ![John\_Jarvis](https://avatars.discourse-cdn.com/v4/letter/j/e47774/32.png) [@John\_Jarvis](https://forum.ansible.com/u/John_Jarvis)\
**Post date:** [October 21, 2013, 2:29pm UTC](https://forum.ansible.com/t/setting-vars-conditionally-within-a-role/13728/2 "2013-10-21T14:29:46Z")

</div>

I think the way I would do this would be to create a var named  
"snmp\_group" in vars/{{ ansible\_os\_family}}.yml which would take on  
different values for different OS types.  
I'm not sure if there is a better way but even if there was I think  
that's a better/cleaner way of specifying it rather than adding logic  
in your play to set it.  
-John

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [October 22, 2013, 1:20am UTC](https://forum.ansible.com/t/setting-vars-conditionally-within-a-role/13728/3 "2013-10-22T01:20:39Z")

</div>

There’s not currently a way to set variables conditionally in a role.

What normally happens here is you would use “group\_by” to determine which roles, or role variations, to apply.

---

<div class="post-metadata">

**Author:** ![Brian\_Candler](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@Brian\_Candler](https://forum.ansible.com/u/Brian_Candler)\
**Post date:** [October 22, 2013, 8:43am UTC](https://forum.ansible.com/t/setting-vars-conditionally-within-a-role/13728/4 "2013-10-22T08:43:49Z")

</div>

I am trying to avoid duplicating complex tasks when they vary by only one parameter. The following is a real example:

- name: add executables  
action: copy src={{item}} dest=/{{item}} mode=750 group=wheel  
with\_items:
- usr/sbin/snmpd-smartctl-connector
- usr/sbin/snmpd-mdraid-connector
- usr/sbin/update-mdraid-cache
- usr/sbin/update-smartctl-cache  
notify: restart snmpd

when: ansible\_os\_family==‘RedHat’

- name: add executables  
action: copy src={{item}} dest=/{{item}} mode=750 group=snmp  
with\_items:
- usr/sbin/snmpd-smartctl-connector
- usr/sbin/snmpd-mdraid-connector
- usr/sbin/update-mdraid-cache
- usr/sbin/update-smartctl-cache  
notify: restart snmpd

when: ansible\_os\_family==‘Debian’

What I want to say is:

- when ansible\_os\_family==‘Debian’, set variable snmp\_group=snmp
- when ansible\_os\_family==‘RedHat’, set variable snmp\_group=wheel
- write the task once, with group={{snmp\_group}}

It seems there is no good way of doing this in ansible. Options are:

1. Write the tasks multiple times with conditions, as shown above
2. Split into two separate but almost identical roles in separate files. Use groups to select the correct role. That was your suggestion. I think it makes maintaining the logic harder because it’s duplicated in different parts of the filesystem, and it puts the onus on the role user to select the correct role.
3. Set up vars from the playbook: this means the role is split into two parts which you must remember to invoke correctly. It’s because playbooks have a feature (vars\_files) that roles don’t.

- hosts: xxx  
vars\_files:
- roles/snmp/vars/{{ansible\_os\_family}}.yml  
roles:
- snmp

1. Use inline jinja2 conditionals in vars/main.yml. This seems like the least bad option here.

[roles/snmp/vars/main.yml]  
snmp\_group: “{% if ansible\_os\_family==‘RedHat’ %}wheel{% else %}snmp{% endif %}”

1. Maybe write a parameterised role, and have two other roles snmp\_redhat and snmp\_debian which call it via ‘meta’, passing the correct value for snmp\_group? Obscure, and in any case the meta roles can only be executed before the roles within the main role.

---

<div class="post-metadata">

**Author:** ![C\_Morgan\_Hamill](https://avatars.discourse-cdn.com/v4/letter/c/ebca7d/32.png) [@C\_Morgan\_Hamill](https://forum.ansible.com/u/C_Morgan_Hamill)\
**Post date:** [October 22, 2013, 12:55pm UTC](https://forum.ansible.com/t/setting-vars-conditionally-within-a-role/13728/5 "2013-10-22T12:55:22Z")

</div>

Excerpts from candlerb's message of 2013-10-22 04:43:49 -0400:

> - when ansible\_os\_family=='Debian', set variable snmp\_group=snmp  
> - when ansible\_os\_family=='RedHat', set variable snmp\_group=wheel

You can do something like this:

- set\_fact: snmp\_group=snmp  
&nbsp;&nbsp;&nbsp;when: ansible\_os\_family == 'Debian'

- set\_fact: snmp\_group=wheel  
&nbsp;&nbsp;&nbsp;when: ansible\_os\_family == 'RedHat'

---

<div class="post-metadata">

**Author:** ![lucc](https://avatars.discourse-cdn.com/v4/letter/l/34f0e0/32.png) [@lucc](https://forum.ansible.com/u/lucc)\
**Post date:** [October 22, 2013, 1:02pm UTC](https://forum.ansible.com/t/setting-vars-conditionally-within-a-role/13728/6 "2013-10-22T13:02:09Z")

</div>

I guess the following would work:

- set\_fact: snmp\_group="wheel"  
&nbsp;&nbsp;&nbsp;when: ansible\_os\_family=='RedHat'

- set\_fact: snmp\_group="snmp"  
&nbsp;&nbsp;&nbsp;when: ansible\_os\_family=='Debian'

- copy: src={{item}} dest=/{{item}} mode=750 group={{snmp\_group}}  
&nbsp;&nbsp;&nbsp;with\_items:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- usr/sbin/snmpd-smartctl-connector  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- usr/sbin/snmpd-mdraid-connector  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- usr/sbin/update-mdraid-cache  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- usr/sbin/update-smartctl-cache  
&nbsp;&nbsp;&nbsp;&nbsp;notify: restart snmpd

s  
Luciano

---

<div class="post-metadata">

**Author:** ![Brian\_Candler](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@Brian\_Candler](https://forum.ansible.com/u/Brian_Candler)\
**Post date:** [October 22, 2013, 1:12pm UTC](https://forum.ansible.com/t/setting-vars-conditionally-within-a-role/13728/7 "2013-10-22T13:12:47Z")

</div>

It does work, thank you !

I didn’t come across the set\_fact module before, because:

1. it is not mentioned in [http://www.ansibleworks.com/docs/playbooks\_variables.html](http://www.ansibleworks.com/docs/playbooks_variables.html)

2. it doesn’t have “var” in its name

Regards,

Brian.

---

<div class="post-metadata">

**Author:** ![lucc](https://avatars.discourse-cdn.com/v4/letter/l/34f0e0/32.png) [@lucc](https://forum.ansible.com/u/lucc)\
**Post date:** [October 22, 2013, 1:20pm UTC](https://forum.ansible.com/t/setting-vars-conditionally-within-a-role/13728/8 "2013-10-22T13:20:40Z")

</div>

Sorry about the dup!

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [October 22, 2013, 2:43pm UTC](https://forum.ansible.com/t/setting-vars-conditionally-within-a-role/13728/9 "2013-10-22T14:43:09Z")

</div>

set\_fact is mentioned in the modules documentation.

I agree it’s named a bit strangely, but we don’t want to change it.

Conditional vars from roles is something we need to think about a bit.

---

<div class="post-metadata">

**Author:** ![Mark\_Casey](https://avatars.discourse-cdn.com/v4/letter/m/b4bc9f/32.png) [@Mark\_Casey](https://forum.ansible.com/u/Mark_Casey)\
**Post date:** [October 22, 2013, 6:49pm UTC](https://forum.ansible.com/t/setting-vars-conditionally-within-a-role/13728/10 "2013-10-22T18:49:27Z")

</div>

A question on the use case: Is that example used to add new things to existing hosts, or to initially configure recently created hosts? Also (if this is for new hosts), do you use both OS families or are you future-proofing in case you ever need to do so?

---

<div class="post-metadata">

**Author:** ![Mark\_Casey](https://avatars.discourse-cdn.com/v4/letter/m/b4bc9f/32.png) [@Mark\_Casey](https://forum.ansible.com/u/Mark_Casey)\
**Post date:** [October 22, 2013, 6:52pm UTC](https://forum.ansible.com/t/setting-vars-conditionally-within-a-role/13728/11 "2013-10-22T18:52:14Z")

</div>

Wait are you saying if I created Debian.yml in a role’s vars folder and then call that role then all the Debian hosts would import that file? Or, just that I could create Debian.yml and do an ‘include:’ for vars/{{ ansible\_os\_family}}.yml manually?

---

<div class="post-metadata">

**Author:** ![Brian\_Candler](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@Brian\_Candler](https://forum.ansible.com/u/Brian_Candler)\
**Post date:** [November 4, 2013, 5:51pm UTC](https://forum.ansible.com/t/setting-vars-conditionally-within-a-role/13728/12 "2013-11-04T17:51:58Z")

</div>

I have both Ubuntu and CentOS hosts that I’m managing, and I have a fairly complicated role for configuring snmpd (which includes the mad-hacking MDRAID and SMARTCTL MIBs) that I want to share between them.

This role is generally run when the machine is first installed, but it can be re-run e.g. to push out a modified version of the mad-hacking scripts, new community string etc.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [November 4, 2013, 11:33pm UTC](https://forum.ansible.com/t/setting-vars-conditionally-within-a-role/13728/13 "2013-11-04T23:33:56Z")

</div>

This was added already on the 1.4 branch.

Please see this thread.

[https://groups.google.com/forum/#!msg/Ansible-project/7Lnf5uuCWCY/-JWECvkiyxMJ](https://groups.google.com/forum/#!msg/Ansible-project/7Lnf5uuCWCY/-JWECvkiyxMJ)
