Every Ansible run targets hosts from an inventory; groups are how you aim tasks at the right machines.
The inventory says which hosts exist and how to reach them. It can be a static file (INI or YAML), a directory of files, or a dynamic inventory plugin.
In a YAML inventory, groups contain hosts, vars and children (nested groups). Two groups always exist: all and ungrouped. A host may belong to several groups (web and prod), which lets you target by role or by environment.
Connection variables per host or group:
ansible_host: the address to connect to, when the inventory name is just a label,ansible_user,ansible_port,ansible_ssh_private_key_file,ansible_python_interpreter: rarely needed now, as Ansible discovers it,ansible_connection: localfor the control node itself.
Ranges save typing: web[01:10].example.com.
Variables are better kept out of the inventory file in group_vars/ and host_vars/ directories next to it: group_vars/web.yml, host_vars/db1.yml, group_vars/all.yml.
Inspect with ansible-inventory -i inventory.yml --graph and --host web1 to see a host's merged variables.
Patterns select hosts on the command line and in plays: web, web:db (union), web:&prod (intersection), all:!staging (exclusion), and --limit narrows any run.
Example
# inventory.yml
all:
children:
web:
hosts:
web1: {ansible_host: 10.0.1.11}
web2: {ansible_host: 10.0.1.12}
db:
hosts:
db1: {ansible_host: 10.0.2.21, ansible_user: admin}
prod:
children: {web: {}, db: {}}
vars:
ansible_user: deploy
# ansible-inventory -i inventory.yml --graph
# @all:
# |--@ungrouped:
# |--@web:
# | |--web1
# ...
# ansible -i inventory.yml 'prod:!db' --list-hosts # web1, web2Remember
- Groups with hosts, vars and children; all and ungrouped always exist
- Keep variables in group_vars/ and host_vars/
- Patterns like web:&prod and --limit select hosts
Watch out for
- Putting many variables inline in the inventory instead of group_vars, making them hard to find and override.