Chapter 4: Managing Variables and Facts
Host and group variables, and precedence
A variable can be set for every host, for a group, for a single host, for one play, or just for one run of a playbook. When the same name is set in more than one place, Ansible needs a rule to decide which value wins. That rule is precedence.
- Set host and group variables, preferably in
host_varsandgroup_varsdirectories. - Override any variable for one run with extra variables.
- Predict which value wins when a variable is defined in several places.
Where variables can live
You can define a variable at very different scopes:
- for all hosts, or a group of hosts, or one host, usually in inventory-related files;
- as a fact that Ansible discovers from the host itself;
- inside a playbook, for one play, or for one task;
- on the command line, for one run, as an extra variable with
-eor--extra-vars.
Variable precedence
When the same variable name is set in several places with different values, the one with the highest precedence wins. This is the simplified order the course uses, from lowest to highest:
- Group variables defined in the inventory
- Group variables in files in a
group_varsdirectory - Host variables defined in the inventory
- Host variables in files in a
host_varsdirectory - Host facts, discovered at run time
- Play variables (
varsandvars_files) - Task variables
- Extra variables on the command line
Two patterns fall out of that list. Narrower beats wider: a host variable beats a group variable, and a group variable for one group beats one set for all. The playbook beats the inventory: anything set in a play overrides inventory variables. And extra variables beat everything.
The full precedence list in the Ansible documentation has more than twenty levels, including role defaults, which you will meet in chapter 8. The eight above cover everything in this chapter.
Host and group variables in the inventory
Inventory variables fall into two groups. Host variables apply to one host. Group variables apply to every host in a group, or in a group of groups. Host variables beat group variables, and playbook variables beat both.
The oldest way to set them is directly in the inventory file.
One host
[servers]
demo.example.com ansible_user=joeansible_user is set only for demo.example.com.
A group
[servers]
demo1.example.com
demo2.example.com
[servers:vars]
user=joeA [group:vars] section sets user for every host in servers.
A group of groups
[servers1]
demo1.example.com
demo2.example.com
[servers2]
demo3.example.com
demo4.example.com
[servers:children]
servers1
servers2
[servers:vars]
user=joeAll four hosts inherit user through the parent group.
This works, but it mixes host lists with settings, makes the inventory harder to read, and uses an older syntax. You will still see it in existing projects.
Using group_vars and host_vars directories
Create the two directories next to your inventory (or your playbook). Inside them:
group_vars/GROUPNAMEholds variables for that group;host_vars/HOSTNAMEholds variables for that host.
Each file is plain YAML, exactly like a vars block:
user: joeHere is the course's two-datacenter example. datacenters is a parent group of datacenter1 and datacenter2, and each level sets a package variable. Pick a host to see which files apply to it and which value wins. Click a file to create or delete it and see the answer change.
The same project, as a tree:
Extra variables from the command line
Extra variables beat every other definition. They are handy for a one-off run with a different value, without editing any file:
[user@demo ~]$ ansible-navigator run main.yml -e "package=apache"You can pass -e several times, or several key=value pairs in one quoted string.
- `group_vars/webservers` sets `port: 80`, `host_vars/servera` sets `port: 8080`, and the play has `vars: { port: 8443 }`. What does servera use?
- Same project, but you remove the play variable. What does servera use now?
- How do you override a variable for a single run without editing any file?
- What name must the file have to hold variables for the group `db_servers`?
Takeaway
Set host and group variables, preferably in host_vars and group_vars directories. Use the chapter lab to check this on a real host.