Ansible — Inventory Management

@amitmund July 30, 2026

Chapter 2 — Inventory Management

1. Theory

Inventory is Ansible's source of truth for "what hosts exist and how are they grouped." It can be static (INI or YAML file) or dynamic (a script/plugin querying a live source like AWS or a CMDB). Hosts can belong to multiple groups, and groups can nest (groups of groups), with variables resolved via a defined precedence order.

2. Internal Working

At startup, Ansible builds an in-memory graph: hosts → groups → group variables, plus a special all group containing everything. Variable precedence (lowest to highest, among inventory sources) is roughly: group_vars/allgroup_vars/<group>host_vars/<host> → inventory file [group:vars] entries closer to the host. Command-line -e extra vars always win over all of these.

3. Diagram

                 all
              /       \
           web          db
         /    \           \
      web1    web2        db1
   (host_vars/web1.yml overrides group_vars/web.yml overrides group_vars/all.yml)

4. Commands

ansible-inventory -i inventory.ini --list          # dump resolved inventory as JSON
ansible-inventory -i inventory.ini --graph          # visualize group nesting
ansible web1 -i inventory.ini -m debug -a "var=hostvars[inventory_hostname]"
ansible-playbook site.yml --limit web1              # restrict run to one host

5. Code Examples

# inventory.ini — nested groups
[web]
web1 ansible_host=10.0.0.11
web2 ansible_host=10.0.0.12

[db]
db1 ansible_host=10.0.0.21

[production:children]
web
db

[production:vars]
env=prod
# group_vars/web.yml
http_port: 8080

# host_vars/web1.yml
http_port: 9090   # overrides group_vars/web.yml for this one host

6. Real-world Example

A company has staging and production environments with identical roles (web, db, cache) but different scale. They use two inventory files (inventory/staging.ini, inventory/production.ini) with the same group structure, so the exact same playbooks run unmodified against either — only the inventory changes.

7. Production Example

At scale, static INI files become unmanageable (hundreds of hosts churn constantly in cloud environments) — production setups almost always move to dynamic inventory plugins (e.g. amazon.aws.aws_ec2) that query live infrastructure by tag, combined with group_vars still stored in version control for anything static (credentials excluded, those go in Vault — Chapter 8).

8. Common Mistakes

  • Defining the same variable in both group_vars and directly in the inventory file and being surprised which one "wins" — precedence rules are easy to get backwards.
  • Forgetting [group:children] syntax requires the child group to already be defined elsewhere in the file.
  • Using --limit with a pattern that matches zero hosts and not noticing the playbook "succeeded" trivially with nothing to do.

9. Troubleshooting

Symptom Likely Cause Fix
Variable has unexpected value Precedence conflict across group_vars/host_vars Run ansible-inventory --list to see resolved values per host
[group:children] group not recognized Child group name typo or defined after use Verify exact group names with --graph
--limit matches nothing, playbook "succeeds" Pattern typo or host not in inventory Confirm with ansible-inventory --list first

10. Security Notes

  • Never store plaintext secrets in group_vars/host_vars committed to version control — use Ansible Vault (Chapter 8) for anything sensitive.
  • Dynamic inventory credentials (cloud API keys) should themselves come from environment variables or a secrets manager, not hardcoded in the inventory plugin config.

11. Interview Questions

  1. Static vs dynamic inventory — when would you use each? Static for small/stable fleets; dynamic for cloud environments where hosts change frequently.
  2. What does [production:children] mean? Defines production as a group containing the members of the listed child groups (web, db), not literal child group syntax for hosts directly.
  3. What's the variable precedence between group_vars and host_vars? host_vars (more specific) overrides group_vars (less specific).
  4. How do you preview resolved inventory without running a playbook? ansible-inventory --list or --graph.
  5. What does --limit do? Restricts a playbook run to a subset of the inventory matching a host/group pattern.

12. Hands-on Lab

  1. Build the nested inventory above with web, db, and production groups.
  2. Set http_port: 8080 in group_vars/web.yml and override it to 9090 in host_vars/web1.yml.
  3. Run ansible-inventory --list and confirm web1 shows 9090 while web2 shows 8080.
  4. Run a playbook with --limit web1 and confirm only that host is targeted.

13. Hacks

  • ansible-inventory --graph --vars shows both the group tree and every variable in one view — faster than cross-referencing multiple files by hand.
  • Host patterns support boolean logic: ansible-playbook site.yml --limit 'web:!web2' targets all of web except web2.

14. Workarounds

  • If you need per-environment variable overrides without duplicating entire inventory files, use one inventory with an env group variable and conditionals in playbooks rather than maintaining parallel file trees.

15. Exercises

  • Add a cache group and make it a child of production alongside web and db.
  • Deliberately create a precedence conflict (same var in group_vars/all and host_vars/<host>) and predict the resolved value before checking with ansible-inventory.

16. Quiz

  1. What command shows the fully resolved inventory as JSON?
  2. Which wins: a variable set in group_vars/web.yml or host_vars/web1.yml?
  3. What syntax nests one group inside another?
  4. What flag restricts a playbook run to specific hosts?
  5. Where should cloud API credentials for dynamic inventory NOT be stored?

Answer Key

  1. ansible-inventory --list
  2. host_vars/web1.yml
  3. [groupname:children]
  4. --limit
  5. Hardcoded directly in the dynamic inventory plugin config file (in version control)
0 Likes
41 Views
0 Comments

Filters

No filters available for this view.

Reset All