Free — no signup required

Variables and Precedence

2 min read

Making Automation Flexible

Hardcoding values like package names, usernames, file paths, or port numbers into tasks makes your automation brittle and environment-specific. Variables decouple the logic of your automation from the specific values it operates on, allowing the same playbook to configure a development server differently from a production server.

Variables are referenced using Jinja2 double-brace syntax: {{ variable_name }} — a task that installs "{{ web_package }}" runs identically everywhere, with the actual package name supplied separately rather than hardcoded as nginx directly in the task. Variables can be defined in many places: in the playbook itself, in inventory files, in dedicated group_vars/ and host_vars/ files, in role defaults, or passed directly on the command line.

The Precedence Hierarchy

When the same variable is defined in multiple places, Ansible uses a strict precedence order to determine which value wins. Understanding this hierarchy is essential for building flexible, environment-aware automation.

Simplified hierarchy (lowest to highest priority):

Priority Location Use Case
1 (lowest) roles/x/defaults/main.yml Sensible defaults, easily overridden
2 Inventory group_vars/all Org-wide defaults
3 Inventory group_vars/<group> Environment or role-specific values
4 Inventory host_vars/<host> Per-host overrides
5 Playbook vars: section Playbook-level values
6 roles/x/vars/main.yml Role internal variables (harder to override)
7 include_vars / set_fact Runtime-computed values
8 (highest) -e "var=value" on CLI Emergency overrides, CI/CD injection

The practical pattern: define defaults in roles/x/defaults/main.yml, environment-specific values in group_vars/, and use -e only for one-off overrides or CI/CD pipeline injection (e.g., passing a build version number at deploy time).

A common mistake is defining variables in roles/x/vars/main.yml (priority 6) when you intend them to be overridable — they won't be, because vars/ has higher precedence than inventory variables. Use defaults/ for anything you want operators to be able to override.

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free