Ansible: Variables scope and precedence

By 2020-06-04Blog

Introduction

Variable scoping can be quite complicated on Ansible and it’s important to know what variable your playbook is going to be using. But sometimes it’s not as easy as it may appear. The documentation on Ansible’s website explains this but I’d like to run you through a scenario we found where the results were not what you would expect them to be.

Recently whilst working on a deployment where we had the same role applied to a group of servers twice with different configurations we found that it wasn’t working for us. We did a bit of investigation and we found that some of the variable precedence were not behaving as we were expecting them to.

https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#ansible-variable-precedence

The scenarios below demonstrate the problem on tests 4 and 5.

Test framework

I’m going to use a simple playbook with a single role which prints variable content to the screen.

The contents of for the role is

and has

Test 1: Load the role

Playbook

Result:
Explanation: It simply takes the default value from the role

Test 2: Override the default with a new value

Result:
Explanation: New value displayed as expected

Test 3: Override variable from within the role

Result:
Explanation: New value displayed as expected

Test 4: Load the role twice and change the default value for one of them

Result: is displayed twice, one for each role
Explanation: This is an unexpected result. You would have thought the result would be for the first time the role loads and for the second attempt but Ansible seems to override the value.

Test 5: Change the order of loading from Test 4

Result: is displayed twice, one for each role
Explanation: This is another unexpected result. Logic would dictate that the first one should be and for the second attempt. The order in which the roles are defined does not affect the result.

Test 6: Override value for both roles

Result: and
Explanation: This is exactly what you would expect as you’re changing the default value.

Test 7: Set global variable and override on role

Result: on both output
Explanation: This is yet another unexpected result similar to tests 4 and 5. The local variable set for a single role seems to override the whole playbook.

Test 8: Override variable from command line

and we’re running the playbook using

Result:
Explanation: Ansible documentation states that the command line has the highest precedence and it stands to reason that all the other variables are ignored.

Test 9: Change variable with

Result: for both roles
Explanation: This is expected as has precedence over roles.

Test 10: Import variable from files

The variable is moved into two files, one defines Wednesday and loaded first and the other one sets the value of Friday and it is loaded last.

Result:
Explanation: This is expected. The last value overrides the first one.

Summary

Some of the results where surprising to me.

https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#ansible-variable-precedence