2
votes

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 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] => 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?

2
I don't get what you are attempting to accomplish. Why is: # 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 when: libffi-dev_ver is defined not enough?Alien Life Form

2 Answers

3
votes

The problem was that the variable 'libffi-dev_ver' I declared is actually a Jinja2 identifier 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 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. This group contains the web server where I want to install the libffi-dev package. 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.

0
votes

I don't get what you are attempting to accomplish. Why is:

# 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
  when: libffi-dev_ver  is defined

not enough?