unit 3 · Inventory
Patterns, --limit & per-env inventories
Deciding exactly which hosts a run touches
you may want to read 8 · Inventory: INI and YAML first — but nothing is locked
tl;dr
- Patterns pick hosts at run time: all, web*, web:&staging (in both), web:!db (web minus db).
- --limit narrows any run to the hosts you name — the re-run and debugging flag.
- One inventory directory per environment is the guardrail that stops a staging run touching prod.
why it matters Target the wrong hosts and Ansible cheerfully configures the wrong hosts — patterns, --limit and per-environment inventories are the three controls that decide where a run lands, prod included.
Lesson 8 gave you an inventory full of groups. Every command since has opened
with a target — web, all — and those are the two simplest cases of
a pattern , the expression that decides which inventory hosts
a run touches. Nothing in Ansible executes anywhere until a pattern has said
where.
Four forms cover most of what you’ll see:
ansible all -m ansible.builtin.ping # every host in the inventory
ansible 'web*' -m ansible.builtin.ping # wildcard: web01, web02, webcache...
ansible 'web:&staging' -m ansible.builtin.ping # in web AND in staging
ansible 'web:!db' -m ansible.builtin.ping # in web but NOT in dbRead the last two as set operations on groups. web:&staging is an
intersection — only hosts that belong to both groups. web:!db is an
exclusion — the web group with the db members subtracted. The quotes are
for your shell, not Ansible: ! and & mean things to bash. One more you’ll
meet constantly: a bare : between two group names is a union — web:db
means everything in either group.
--limit: narrow the run you already wrote
--limit is the outside control: a run-control flag that narrows any run to
the hosts you name, without editing a thing. When you reach playbooks in
unit 4, each play declares its own targets — --limit cuts below that
declaration.
# the full run, as the play targets it
ansible-playbook site.yml -i inventories/staging/
# identical run, narrowed to the one host that failed
ansible-playbook site.yml -i inventories/staging/ --limit web01That second line is why --limit sits in the debugging toolkit next to
-vvv and --check: one host broke mid-run, you fix the cause, you re-run
against just that host instead of hammering the whole fleet again.
One inventory directory per environment
Here is the structural habit that matters more than any pattern syntax. Best practice is a separate inventory directory per environment, each carrying its own group_vars and host_vars :
inventories/
production/
hosts.yml # prod hosts and groups
group_vars/ # prod values live with prod
host_vars/
staging/
hosts.yml # same group names, different machines
group_vars/
host_vars/You choose the environment the moment you type -i inventories/production/.
That is the entire mechanism behind the standup phrase “run the playbook
against prod” — same playbook, prod inventory. Keep group_vars/all.yml
minimal; anything environment-specific belongs inside that environment’s
directory, not in a shared file both environments read.
Before trusting any inventory, look at what it actually contains:
ansible-inventory --graph -i inventories/staging/ prints the group tree
Ansible resolved. Make that your reflex before the first run against any
inventory you didn’t write — the same cheapest-fact-first instinct as the
ping in lesson 7, one level up.
at work, this sounds like
- “Run the playbook against prod.”
- Execute it with the production inventory — ansible-playbook site.yml -i inventories/prod/.
self-check — recall, not a test
1 What do web:&staging and web:!db each match?
2 A playbook run failed on one host. How do you re-run it against just that host without editing anything?
3 Why one inventory directory per environment instead of one big inventory holding prod and staging groups?
lab (optional — never required)
Build inventories/staging/ and inventories/production/ with one host each, inspect both with ansible-inventory --graph -i <dir>, then ping with a pattern and again with --limit.
needs: The control node from lesson 5.