# Variable precedence and making roles work across distributions

**URL:** <https://forum.ansible.com/t/variable-precedence-and-making-roles-work-across-distributions/15501>\
**Category:** Ansible Project\
**Created:** [June 19, 2014, 12:40pm UTC](https://forum.ansible.com/t/variable-precedence-and-making-roles-work-across-distributions/15501 "2014-06-19T12:40:08Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jeff\_Geerling](https://avatars.discourse-cdn.com/v4/letter/j/13edae/32.png) [@Jeff\_Geerling](https://forum.ansible.com/u/Jeff_Geerling)\
**Post date:** [June 19, 2014, 12:40pm UTC](https://forum.ansible.com/t/variable-precedence-and-making-roles-work-across-distributions/15501/1 "2014-06-19T12:40:08Z")

</div>

The technique I usually use for making a role work cross-distro is to do two things:

**For variables** : Include a variables file named {{ ansible\_os\_family }}.yml (then stick ‘Debian.yml’ and ‘RedHat.yml’, etc. into the role’s vars folder.

**For tasks** : Add “when: ansible\_os\_family == ‘Distribution’” to the task (where ‘Distribution’ is Debian, RedHat, etc.).

This presents an issue; for normal variables that I want to let role users override easily, I put the variables in the roles ‘defaults/main.yml’ file. But for distribution-specific variables (for example, “java\_packages” in my [Java role](https://github.com/geerlingguy/ansible-role-java)), I have to put the distro-specific vars include files in the main ‘vars’ folder, so those variables have higher precedence than, say, group\_vars.

I’ve bumped into this a few times, but could usually find other ways of getting the variable I want to take hold. For some users, it’s not possible, thus I have bugs like: [Openjdk-7 cannot be installed](https://github.com/geerlingguy/ansible-role-java/issues/1).

What are some possible fixes/other ways to do this?

I could set up a variable for each distro (like “java\_redhat\_packages” and “java\_debian\_packages”, but in some roles, where 5-10 of these would be needed, I fear maintainability and simplicity would be sacrificed for variable overridability…

---

<div class="post-metadata">

**Author:** ![drybjed](https://avatars.discourse-cdn.com/v4/letter/d/48db29/32.png) [@drybjed](https://forum.ansible.com/u/drybjed)\
**Post date:** [June 19, 2014, 12:47pm UTC](https://forum.ansible.com/t/variable-precedence-and-making-roles-work-across-distributions/15501/2 "2014-06-19T12:47:49Z")

</div>

How about this solution?

In `defaults/main.yml`:

java\_distribution\_packages:  
Debian: [‘openjdk-7’, ‘java-stuff’]  
RefHat: [‘java-runtime-7’, ‘other-stuff’]

And then, in `tasks/main.yml`:

- {{ ansible\_pkg\_mgr }}: name={{ item }} state=latest  
witn\_items: java\_distribution\_packages[ansible\_os\_family]

I think that should work fine and let you override java\_distribution\_packages in inventory.

Maciej

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [June 19, 2014, 4:49pm UTC](https://forum.ansible.com/t/variable-precedence-and-making-roles-work-across-distributions/15501/3 "2014-06-19T16:49:30Z")

</div>

Never do this, ansible\_pkg\_mgr does not allow the with\_items block to be grouped into a single yum/apt transaction, which results in much slower package installations.

I understand why it’s appealing, but really don’t … you’ll also find that the yum and apt modules have different options you may want to use from time to time anyway.

---

<div class="post-metadata">

**Author:** ![drybjed](https://avatars.discourse-cdn.com/v4/letter/d/48db29/32.png) [@drybjed](https://forum.ansible.com/u/drybjed)\
**Post date:** [June 19, 2014, 4:53pm UTC](https://forum.ansible.com/t/variable-precedence-and-making-roles-work-across-distributions/15501/4 "2014-06-19T16:53:36Z")

</div>

Will this work ok if I use apt: module directly instead? For different package lists in Debian and Ubuntu, for example.

---

<div class="post-metadata">

**Author:** ![James\_Cammarata](https://avatars.discourse-cdn.com/v4/letter/j/7c8e57/32.png) [@James\_Cammarata](https://forum.ansible.com/u/James_Cammarata)\
**Post date:** [June 19, 2014, 4:56pm UTC](https://forum.ansible.com/t/variable-precedence-and-making-roles-work-across-distributions/15501/5 "2014-06-19T16:56:17Z")

</div>

You can achieve pretty much the same thing by using group\_by or conditional includes along with the variable structure you’ve defined, without loosing the benefits Michael mentioned.

It should work fine with the apt or yum (or other package modules).

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [June 19, 2014, 9:28pm UTC](https://forum.ansible.com/t/variable-precedence-and-making-roles-work-across-distributions/15501/6 "2014-06-19T21:28:51Z")

</div>

group\_by is awesome.

- hosts: webservers  
group\_by: key=webservers\_{{ ansible\_os\_family }}

- hosts: webservers\_RedHat  
roles:

- …
