Skip to content

Lesson 2 of 9 · 22m

Inventories: Groups, Variables, and Dynamic Sources

Static INI and YAML inventories, group_vars/host_vars layering, host patterns, and dynamic inventory plugins — where your fleet's truth actually lives.

Every Ansible horror story I've debugged started with the inventory, not the playbook. "Why did the DB restart?" — because db01 was accidentally also in [webservers] and the playbook targeted webservers. The inventory is your fleet's source of truth; treat it like a schema, not a text file.

A real inventory, INI flavor

# inventory/production.ini
[webservers]
web[01:04].prod.acme.corp

[dbservers]
db01.prod.acme.corp primary=true
db02.prod.acme.corp

[prod:children]
webservers
dbservers

[group:children] builds groups-of-groups; [group:vars] would attach variables to every member the same way. Host ranges (web[01:04]) keep the file honest, and primary=true on db01 is an inline host var — fine for a flag, wrong for anything long.

Patterns are a query language

ansible-playbook site.yml -l 'webservers:&prod'    # intersection
ansible-playbook site.yml -l 'webservers:!web02*'  # exclusion
ansible-playbook site.yml -l 'webservers[0]'       # first host only — a canary

& intersects, ! excludes, : or , unions — "canary deploy to one web node" without editing files.

group_vars and host_vars: the layering

inventory/
  group_vars/
    all.yml            # everything
    webservers.yml     # nginx config, ports
    dbservers.yml      # postgres settings
  host_vars/
    db01.prod.acme.corp.yml   # this host only

Resolution: host_vars > group_vars (deepest group wins) > group_vars/all. This is where "configured on db01 but not db02" comes from — an override file exists for one host and nobody remembered.

When the fleet moves: dynamic inventory

Static files rot the day autoscaling appears. Inventory plugins query the source at runtime:

# inventory/aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions: [us-east-1]
keyed_groups:
  - key: tags.Environment
    prefix: env
filters:
  instance-state-name: running

Now env_production exists as a group, computed from live EC2 tags — same mechanism for GCP, Azure, VMware, NetBox. ansible-inventory --graph renders the resulting tree; run it before every mysterious targeting problem.

Field notes

  • Duplicate group membership is legal and silently merges variables — ansible-inventory --host db01 shows the resolved view, not the file view.
  • localhost with connection: local is the escape hatch for API-only targets (cloud provisioning, k8s).
  • Put secrets in inventory vars only via vault — group_vars/all.yml in plaintext is how DB passwords end up in git history.