unit 3 · Inventory

Patterns, --limit & per-env inventories

Deciding exactly which hosts a run touches

essential · 7 min · linux + windows

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. Those are the simplest cases of a pattern , the expression deciding which inventory hosts a run touches. Nothing executes until a pattern says where.

Four forms cover most cases:

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 db
the four pattern forms, on the ad-hoc command you already know

Read the last two as set operations on groups. web:&staging is an intersection — hosts in both groups. web:!db is an exclusion — web minus the db members. The quotes are for your shell, not Ansible: ! and & mean things to bash. And a bare : between two group names is a union — web:db is everything in either group.

--limit: narrow the run you already wrote

--limit is a run-control flag: it 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 web01
same playbook, progressively smaller blast radius

That second line is why --limit sits in the debugging toolkit next to -vvv and --check. One host broke mid-run? Fix the cause, re-run against just that host — not the whole fleet.

One inventory directory per environment

This habit matters more than any pattern syntax: a separate inventory directory per environment, each with 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/
the environment IS the directory you point -i at

You choose the environment when you type -i inventories/production/. That’s the mechanism behind the standup phrase “run the playbook against prod” — same playbook, prod inventory. Keep group_vars/all.yml minimal. Anything environment-specific belongs in that environment’s directory, not in a shared file both environments read.

Before trusting any inventory, look at what it 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. Same cheapest-fact-first instinct as the ping in lesson 7, one level up.

practice — aim a pattern at this inventory

[web]web01web02web03
[db]db01db02
[staging]web01db01
[prod]web02web03db02

→ web01

covers this lesson’s forms: names, *, : union, :& intersection, :! exclusion

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. 1 What do web:&staging and web:!db each match?

  2. 2 A playbook run failed on one host. How do you re-run it against just that host without editing anything?

  3. 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.

next up 11 · Dynamic inventory & plugins 6 min · unit 3