Ansible: inventory — hosts, groups, vars, targeting¶
Mental model¶
Inventory answers two questions: WHAT machines does Ansible manage, and HOW are they organized. It is a map of names to connection details, grouped for targeting.
What it looks like¶
"I list my servers in a file and Ansible connects to them." People treat inventory as a flat list of IPs and miss the grouping, variable layering, and dynamic generation capabilities.
What it really is¶
- Host: a target machine identified by hostname or IP. Each host can carry host-specific variables.
- Group: a named set of hosts. Groups can nest (children).
- Implicit groups:
all(every host) andungrouped(hosts not in any explicit group) always exist. - Variables: can be set per-host (
host_vars/) or per-group (group_vars/). Directory-based variable files are auto-loaded. - Static inventory: an INI or YAML file you maintain by hand.
- Dynamic inventory: a script or plugin that queries an API (AWS, GCP, etc.) and returns hosts/groups at runtime.
Why it seems confusing¶
Variables come from many sources — inventory, playbooks, roles, CLI, facts. Inventory is just one source, but it is often the first place people put variables, which leads to tangled precedence. Also, INI format and YAML format look completely different but do the same job.
What actually matters¶
- The
hosts:directive in a play selects which inventory hosts run the tasks. It accepts group names, host names, and patterns. - Patterns support union (
:) intersection (:&), and exclusion (:!). Example:webservers:&staging= hosts in BOTH groups. group_vars/andhost_vars/directories alongside your inventory file are auto-loaded — no explicit include needed.- Dynamic inventory lets you avoid stale host lists. Cloud environments should almost always use dynamic inventory.
Common mistakes¶
- Hardcoding IPs when DNS or dynamic inventory would be better.
- Putting secrets directly in inventory files instead of using ansible-vault or an external secrets manager.
- Forgetting that a host can be in multiple groups, and variables from all its groups merge (with precedence rules).
- Ignoring the
ungroupedgroup — hosts not in any explicit group land here and may miss group_vars.
Small examples¶
# inventory.ini — static INI format
[webservers]
web1.example.com
web2.example.com
[dbservers]
db1.example.com ansible_port=5432
[staging:children]
webservers
dbservers
[staging:vars]
env=staging
# Directory-based variables (auto-loaded)
inventory/
hosts.ini
group_vars/
webservers.yml # vars for webservers group
staging.yml # vars for staging group
host_vars/
db1.example.com.yml # vars for one host
# Host patterns in a play
hosts: webservers # all webservers
hosts: webservers:dbservers # union
hosts: webservers:&staging # intersection
hosts: all:!dbservers # everyone except dbservers
One-line summary¶
Inventory defines which machines Ansible manages, how they are grouped, and what variables they carry — and plays target subsets of that inventory using host patterns.