unit 3 · Inventory
group_vars & host_vars
Config files that find their hosts by name
you may want to read 8 · Inventory: INI and YAML first — but nothing is locked
tl;dr
- group_vars/ and host_vars/ sit next to your inventory and auto-load by group and host name.
- Environment config lives here — per group in group_vars, pinned to one machine in host_vars.
- group_vars/all.yml hits every host in the inventory. Keep it minimal.
why it matters Every real repo carries these directories. If you don’t know the files load themselves by name, you’ll hunt for an import that doesn’t exist — and put environment config in all the wrong places.
Lesson 8 gave you groups. This lesson gives them configuration, through two directories next to your inventory file: group_vars and host_vars . The entire trick is in the filenames:
inventory/
├── hosts.yml # your lesson-8 inventory: web, db, all the groups
├── group_vars/
│ ├── all.yml # every host in the inventory — keep it minimal
│ └── web.yml # every host in the web group
└── host_vars/
└── web01.yml # exactly one machine: web01No import line, no path setting, no reference from the inventory. Ansible
auto-loads each file by matching its name against your group and host
names. group_vars/web.yml applies to every host in web;
host_vars/web01.yml to the single host web01. group_vars/all.yml
applies to everything, because every host belongs to the built-in all
group. A vars file is just YAML keys and values:
# loaded automatically for every host in the web group
app_env: staging
http_port: 8080
motd_message: 'managed by ansible - do not hand-edit'Where environment config lives
The rule is blunt: environment config lives here. Ports, service endpoints, tuning values — anything that varies between staging and production belongs in group_vars. Not hardcoded into a playbook, not scattered across the inventory file. When roles arrive in Unit 6, you’ll see the full division of labour: user-tunable defaults in the role, environment values in group_vars.
Two habits separate tidy repos from haunted ones:
- Keep
group_vars/all.ymlminimal. A value there touches every host in the inventory, so it must be genuinely universal. Environment-specific values belong in the environment’s own inventory directory — more on that below. - Use
host_vars/sparingly, for values true of one machine only. If you’re writing the same key into three host files, those hosts want to be a group.
Your inventory now says who your hosts are and what is true about them,
all loaded by naming convention. Real repos go one step further: a separate
inventory directory per environment (inventories/production/,
inventories/staging/), each with its own group_vars and host_vars.
So staging values can never bleed into prod. The structure — plus the
patterns that pick which hosts a run touches — is lesson 10.
self-check — recall, not a test
1 You create group_vars/web.yml. What do you have to add elsewhere so Ansible loads it?
2 An NTP server address differs between staging and production. Where does it belong?
3 Your group_vars value isn’t the one showing up at runtime. What do you know so far, and where’s the full answer?
lab (optional — never required)
Rebuild this lesson’s tree next to your lesson-8 inventory, then prove the values load with an ad-hoc ansible.builtin.debug call against the web group.
needs: The control node and inventory from lessons 5–8.