# How to set an Ansible tier-specific inventory variable?

**URL:** <https://forum.ansible.com/t/how-to-set-an-ansible-tier-specific-inventory-variable/21317>\
**Category:** Ansible Project\
**Created:** [April 29, 2016, 4:41pm UTC](https://forum.ansible.com/t/how-to-set-an-ansible-tier-specific-inventory-variable/21317 "2016-04-29T16:41:00Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Robert\_F](https://avatars.discourse-cdn.com/v4/letter/r/9d8465/32.png) [@Robert\_F](https://forum.ansible.com/u/Robert_F)\
**Post date:** [April 29, 2016, 4:41pm UTC](https://forum.ansible.com/t/how-to-set-an-ansible-tier-specific-inventory-variable/21317/1 "2016-04-29T16:41:00Z")

</div>

Is it possible to create an Ansible inventory variable that isn’t associated with an inventory host or group but the server tier the playbook is run on? I have an Ansible role that installs the libffi-dev package using APT, but I may want to install a different version of that package on each server tier. I’ve created a variable “libffi-dev\_ver” for that purpose. I also have the inventory files “development”, “staging”, and “production” that correspond to each of my tiers.

My role’s main task, which is called from my main site.yml playbook, checks that version variable exists prior to running the role:

# roles/misc\_libs/tasks/main.yml

- include: check\_vars.yml tags=misc\_libs
- include: misc\_libs.yml tags=misc\_libs

check\_vars.yml checks to ensure that the package version variable exists:

# roles/misc\_libs\_tasks/check\_vars.yml

- name: check that required role variables are set  
fail: msg=“{{ item }} is not defined”  
when: not {{ item }}  
with\_items:
- libffi-dev\_ver

The misc\_libs role actually uses that variable to install the package:

# roles/misc\_libs/tasks/misc\_libs.yml

- name: install libffi-dev  
apt: \>  
pkg=libffi-dev={{ libffi-dev\_ver }}  
update\_cache=yes  
cache\_valid\_time=3600  
become: True

My development inventory file looks like this:

# development

[webservers]  
[web01.example.com](http://web01.example.com) ansible\_ssh\_host=\<ip\_address\>

[dev:children]  
webservers

[webservers:vars]  
libffi-dev\_ver=“3.1-2+b2”

When I run this command:

ansible-playbook -i development site.yml -l webservers

I get this Ansible error:

fatal: [[web01.example.com](http://web01.example.com)] =\> error while evaluating conditional: not libffi-dev\_ver

What is the correct way to declare a package versioning variable like this in Ansible? The variable’s value depends on the server tier which indicates to me that it goes in an inventory file since inventory files are server tier-specific. But all inventory variables seem to have to be associated with a host or group. I’ve done that but the role still doesn’t see the variable. I could add a task to the role that detects the server tier and uses a “when” conditional to set the variable accordingly but that solution seems ugly because if you’re installing multiple packages in a role, you’d need three conditionals for each package version variable. I’ve looked through the Ansible documentation and read numerous blog posts on setting up multi-tier playbooks but I don’t see this particular situation addressed. What’s the right way to declare a tier-specific variable like this?

Thanks!

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [April 29, 2016, 5:06pm UTC](https://forum.ansible.com/t/how-to-set-an-ansible-tier-specific-inventory-variable/21317/2 "2016-04-29T17:06:37Z")

</div>

There are several ways.

Make all machines in the development inventory part of the development group, same with other 'tier’s, then you can have ‘tier vars’.

make each var a composite:

libffi:  
dev: 3.1-2+b2  
qa: 3.0-1  
prod: 3.0-1

Then have the ‘tier’ var defined by inventory file (under all:vars), then always acceiss this way: libffi[tier]

---

<div class="post-metadata">

**Author:** ![Robert\_F](https://avatars.discourse-cdn.com/v4/letter/r/9d8465/32.png) [@Robert\_F](https://forum.ansible.com/u/Robert_F)\
**Post date:** [April 29, 2016, 5:23pm UTC](https://forum.ansible.com/t/how-to-set-an-ansible-tier-specific-inventory-variable/21317/3 "2016-04-29T17:23:26Z")

</div>

Thanks. Initially, I did have all machines in my dev inventory a part of a “dev” group but I was getting the same error using that approach. I thought it should work too but it didn’t for some reason. But your idea on making each var a composite is interesting so I’m going to give it a try.

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [April 29, 2016, 5:30pm UTC](https://forum.ansible.com/t/how-to-set-an-ansible-tier-specific-inventory-variable/21317/4 "2016-04-29T17:30:12Z")

</div>

just thought, you dont even need a variable, just the built in for inventory:

tier: ‘{{inventory\_path|basename}}’

---

<div class="post-metadata">

**Author:** ![Robert\_F](https://avatars.discourse-cdn.com/v4/letter/r/9d8465/32.png) [@Robert\_F](https://forum.ansible.com/u/Robert_F)\
**Post date:** [April 29, 2016, 9:59pm UTC](https://forum.ansible.com/t/how-to-set-an-ansible-tier-specific-inventory-variable/21317/5 "2016-04-29T21:59:03Z")

</div>

Brian, I found another way to do this and I’ll post my solution shortly. I think your solution will work too but my solution allows me to keep tier-specific variables in their own separate files. While one could argue that it would be simpler to maintain them if they were all in one file, I kind of like keeping them in separate files. Thanks for your help.

---

<div class="post-metadata">

**Author:** ![Robert\_F](https://avatars.discourse-cdn.com/v4/letter/r/9d8465/32.png) [@Robert\_F](https://forum.ansible.com/u/Robert_F)\
**Post date:** [April 29, 2016, 9:59pm UTC](https://forum.ansible.com/t/how-to-set-an-ansible-tier-specific-inventory-variable/21317/6 "2016-04-29T21:59:28Z")

</div>

The problem was that the variable ‘libffi-dev\_ver’ I declared is actually a Jinja2 [identifier](http://jinja.pocoo.org/docs/dev/api/#notes-on-identifiers) that must adhere to Python 2.x naming rules. The ‘-’ (dash) is an invalid character according to these rules. Once I changed it to an ‘\_’ (underscore), I no longer got the error.

Also, the check\_vars.yml playbook is actually unnecessary. There is an Ansible configuration variable [error\_on\_undefined\_vars](http://docs.ansible.com/ansible/intro_configuration.html#error-on-undefined-vars) which will cause steps containing an undefined variable to fail. Since it’s true by default, I don’t need to run check\_vars.yml as all variables are already being checked.

One place to declare server tier-specific variables seems to be in a file in the group\_vars directory that has the same name as the group which is named after that tier in your inventory file. So in my case my ‘development’ inventory file contains a ‘dev’ child group. Therefore, I created a file ‘group\_vars/dev’ and declared a variable in that file called ‘libffi\_dev\_ver’ which I can reference in my misc\_libs.yml playbook.
