// learn Β· linux Β· rhce Β· 10 min

Ansible variables & facts.

The same variable can be defined in a dozen places β€” what wins is decided by precedence. Watch one value climb a precedence ladder, then meet gathered facts and ansible_facts, register and set_fact, and custom facts.d.

Ansible variables and facts animated tutorial. Defining variables in play vars, vars_files, group_vars and host_vars, inventory, role defaults and vars, and CLI extra-vars; referencing them with Jinja2 templating; the variable precedence ladder where extra-vars win and role defaults lose; gathering facts with gather_facts and the setup module; reading ansible_facts; capturing runtime values with register and set_fact; magic variables; and custom facts in facts.d under ansible_local. RHCE EX294 ready.
// ansible Β· variables & facts

The same variable can be defined in a dozen places. Watch one value, http_port, climb a precedence ladder as more sources define it β€” then meet facts, register, set_fact, and custom facts.d.

// before you start
you should know
  • Β·Know an Ansible inventory, groups, and group_vars
  • Β·Comfortable reading basic YAML and a simple playbook
  • Β·Seen Jinja2 {{ }} templating before (helps, not required)
by the end you'll

Define variables in every common location, reference them with Jinja2, predict which source wins by precedence, gather and read facts, and capture runtime values with register and set_fact.

pace: 10 minutes

ansible β€” step 1 / 6 Β· defining
variable: http_porthighest precedence on top ↑
extra-vars -e
β€” not set β€”
play vars:
β€” not set β€”
host_vars/servera
β€” not set β€”
group_vars/webservers
β€” not set β€”
inventory group_vars/all
http_port = 80← wins
role defaults (roles/web/defaults/main.yml)
http_port = 8080
role defaults always lose ↓

Defining variables β€” many places

A variable can be set in a startling number of places: a play's vars: block, files pulled in with vars_files:, the group_vars/ and host_vars/ directories, the inventory itself, a role's defaults/ and vars/, captured at runtime with register, asserted with set_fact, and passed on the CLI with -e. Names use letters, digits, and underscores and cannot start with a digit. At this stage only the low rungs are set β€” role defaults give http_port its baseline.

$vars:\n http_port: 9000
$# group_vars/webservers.yml\nhttp_port: 8000
$ansible-playbook site.yml -e "http_port=9999"
// key insight

The same variable can be set in a dozen places β€” what actually matters is precedence. Extra-vars (-e) always win; role defaults always lose. Everything else sits on a ladder in between, and for scalars the highest rung wins outright β€” there is no merging. Know the ladder and "why is my variable not the value I set?" stops being a mystery.

// exam-ready Β· variables & facts
$vars:
$vars_files:
$group_vars/NAME.yml
$host_vars/HOST.yml
$-e "k=v"
${{ var }}
${{ var | default(X) }}
$var['key'] / var.key
$gather_facts: true | false
$ansible HOST -m setup
$-a "filter=ansible_*"
$ansible_facts['default_ipv4']['address']
$register: r β†’ r.stdout / r.rc / r.changed
$set_fact: k: v
$inventory_hostname, hostvars, groups
$/etc/ansible/facts.d/*.fact β†’ ansible_local
// check yourself
4 quick questions
Q1

http_port is set in group_vars/webservers (8000) and also passed as -e http_port=9999. Which value does the play use?

Q2

How do you populate ansible_facts for a host?

Q3

What is the difference between register and set_fact?

Q4

A variable's value starts with {{. What must you do in the YAML?

These aren't graded β€” they're just for active recall, which is what actually makes the lesson stick.

πŸ”
// next: repetition & logic

Ansible loops & conditionals

Now that a variable can hold a list or a dict, drive tasks with it: loop over items, gate work with when, and handle each host's data cleanly.

open β†’
// more in systems

keep going β€” these pair well with what you just learned.

see all systems β†’
back to RHCSA / RHCE trackall lessons