Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Ansible roles and variable precedence

After this lesson: I can lay out a role and say which variable wins.

55 min lesson10 commandsAnsible roles lab: a role, handlers and Vault on one Ubuntu VM

A role is a playbook in fixed folders

An Ansible role is a fixed folder layout that holds one reusable piece of a set-up: its tasks, its variables, its files and more. Knowing which folder a variable lives in tells you whether a user can override it, which is the part of roles that surprises people most.

A school that sets up three computer rooms can write one role and reuse it three times.

By the end of this lesson

Note

I can lay out a role and say which variable wins.

Key words

WordWhat it meansExample
Rolea reusable set-up in a fixed folder layout
Playbooka file that says which tasks run on which hosts
Defaultsa role's weakest variables, meant to be overridden
Role varsa role's own variables, which beat the play's
Extra varsvalues typed with -e, the strongest of all-e greeting=Hello
Precedencethe order that decides which variable wins

The cells students fill in are left blank in this preview.

A role has a fixed folder layout

Ansible finds each part of a role by its folder name, so the layout never changes. tasks holds what the role does. defaults and vars hold its variables. templates holds files with gaps to fill, handlers holds tasks that wait to be told, and meta says who made it.

The tool ansible-galaxy builds the empty layout for you, with no network needed.

The folders of a role

FolderWhat it holdsEntry file
tasksthe work the role doesmain.yml
defaultsvariables a user may overridemain.yml
varsvariables the role keeps for itselfmain.yml
templatesfiles with gaps to fillname.j2
handlerstasks that run only when toldmain.yml
metathe role's author and descriptionmain.yml

The cells students fill in are left blank in this preview.

Make a folder for the Ansible work

Command
mkdir -p ~/iac-demo/ansible

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Go into it

Command
cd ~/iac-demo/ansible

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Build the layout of a role called greeter

Command
ansible-galaxy role init --init-path roles greeter

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

List its folders

Command
find roles/greeter -type d | sort

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

When two variables share a name, one wins

The same variable can be set in several places, and Ansible has a fixed order. From weakest to strongest: a role's defaults, then the play's vars, then the role's own vars, then -e on the command line.

So defaults are for values a user is meant to change. vars are for values the role insists on. -e always has the last word.

Worked example: three variables, four places

VariabledefaultsPlay varsRole varsWinner
shop_nameCorner ShopRiverside BakerynoneRiverside Bakery
greetingWelcomenonenoneWelcome
opening_hoursnoneall night09:00 to 17:0009:00 to 17:00

The cells students fill in are left blank in this preview.

Write the role's defaults

Command
printf '%s\n' '---' 'shop_name: Corner Shop' 'greeting: Welcome' > roles/greeter/defaults/main.yml

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Write the role's own vars

Command
printf '%s\n' '---' 'opening_hours: 09:00 to 17:00' > roles/greeter/vars/main.yml

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Write one task that shows all three

Command
printf '%s\n' '---' '- name: Show the sign' '  ansible.builtin.debug:' '    msg: "{{ greeting }} to {{ shop_name }}, open {{ opening_hours }}"' > roles/greeter/tasks/main.yml

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Write a play with two variables

Command
printf '%s\n' '---' '- name: Put up the sign' '  hosts: localhost' '  gather_facts: false' '  vars:' '    shop_name: Riverside Bakery' '    opening_hours: all night' '  roles:' '    - greeter' > sign.yml

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Run it against this machine

The Runs use -i localhost, to say the only host is this machine, and -c local to say there is nothing to connect to. The play sets shop_name, which beats the default, and opening_hours, which the role's own vars should beat. grep msg keeps the one line that shows the result.

Run the play and show the sign

Command
ansible-playbook -i localhost, -c local sign.yml | grep msg

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Run it again with -e values

Command
ansible-playbook -i localhost, -c local sign.yml -e greeting=Hello -e opening_hours=closed | grep msg

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

A common mistake

Warning

Many people put a value they want users to change in vars/main.yml. Role vars beat the play, so nobody can change it except with -e. Put a value in defaults if it may change, and in vars only if it must not.

Four layers in a dozen lines of Python

Code: python
# Each layer overwrites the one before it, weakest first.
defaults = {"shop_name": "Corner Shop", "greeting": "Welcome"}
play_vars = {"shop_name": "Riverside Bakery", "opening_hours": "all night"}
role_vars = {"opening_hours": "09:00 to 17:00"}
extra_vars = {}
final = {}
for layer in [defaults, play_vars, role_vars, extra_vars]:
    for name in layer:
        final[name] = layer[name]
print(final)
# Put "greeting": "Hello" into extra_vars and run it again.

About this lab and its source: Ansible roles lab: a role, handlers and Vault on one Ubuntu VM

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.