Skip to content

Inventory

First PublishedByAtif Alam

The inventory tells Ansible which hosts to manage. It can be a simple text file, a YAML file, or a script that dynamically queries your cloud provider.

The simplest form — a file listing hosts and groups:

inventory.ini
[webservers]
web1.example.com
web2.example.com
192.168.1.50
[dbservers]
db1.example.com
db2.example.com
[loadbalancers]
lb1.example.com

Run against this inventory:

Terminal window
ansible -i inventory.ini webservers -m ping
ansible-playbook -i inventory.ini site.yml

The same inventory in YAML:

inventory.yml
all:
children:
webservers:
hosts:
web1.example.com:
web2.example.com:
192.168.1.50:
dbservers:
hosts:
db1.example.com:
db2.example.com:
loadbalancers:
hosts:
lb1.example.com:

YAML format is more verbose but better for complex inventories with nested variables.

Every host belongs to at least two groups:

  • all — Every host in the inventory.
  • ungrouped — Hosts not in any other group.
[webservers]
web1.example.com
web2.example.com
[dbservers]
db1.example.com
[production:children]
webservers
dbservers

Now production contains all hosts from webservers and dbservers.

YAML equivalent:

all:
children:
production:
children:
webservers:
hosts:
web1.example.com:
web2.example.com:
dbservers:
hosts:
db1.example.com:
[webservers]
web1.example.com ansible_port=2222 http_port=8080
web2.example.com http_port=80
webservers:
hosts:
web1.example.com:
ansible_port: 2222
http_port: 8080
web2.example.com:
http_port: 80

For cleaner organization, use host_vars/ and group_vars/ directories:

inventory/
hosts.yml
group_vars/
all.yml # variables for all hosts
webservers.yml # variables for webservers group
dbservers.yml # variables for dbservers group
host_vars/
web1.example.com.yml # variables for this specific host
group_vars/webservers.yml
http_port: 80
app_env: production
deploy_user: deploy
host_vars/web1.example.com.yml
ansible_port: 2222
http_port: 8080

Special variables that control how Ansible connects:

VariableDefaultPurpose
ansible_hostinventory hostnameIP or hostname to connect to
ansible_port22SSH port
ansible_usercurrent userSSH username
ansible_ssh_private_key_filePath to SSH key
ansible_becomefalseEnable privilege escalation (sudo)
ansible_become_methodsudoHow to escalate (sudo, su, doas)
ansible_python_interpreter/usr/bin/python3Python path on the remote host
[webservers]
web1.example.com ansible_user=deploy ansible_become=true

Patterns let you target specific hosts or groups:

Terminal window
ansible webservers -m ping # all hosts in webservers
ansible dbservers -m ping # all hosts in dbservers
ansible all -m ping # every host
ansible web1.example.com -m ping # single host
ansible 'webservers:dbservers' -m ping # union (both groups)
ansible 'webservers:&production' -m ping # intersection
ansible 'webservers:!web1.example.com' -m ping # exclude a host
ansible '*.example.com' -m ping # wildcard

The same patterns work in playbooks:

- hosts: webservers:&production
tasks:
- name: Deploy app
# ...

Instead of a static file, a script or plugin queries your infrastructure and returns host lists in JSON.

inventory/aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
- us-east-1
filters:
tag:Environment: production
keyed_groups:
- key: tags.Role
prefix: role
- key: placement.availability_zone
prefix: az
compose:
ansible_host: public_ip_address
Terminal window
ansible-inventory -i inventory/aws_ec2.yml --graph # see discovered hosts
ansible -i inventory/aws_ec2.yml role_webserver -m ping
  • azure.azcollection.azure_rm — Azure VMs
  • google.cloud.gcp_compute — GCP instances
  • kubernetes.core.k8s — Kubernetes pods
  • community.docker.docker_containers — Docker containers

Set a default inventory in ansible.cfg so you don’t need -i every time:

# ansible.cfg
[defaults]
inventory = ./inventory/hosts.yml
  • Inventory defines what Ansible manages — hosts, groups, and their variables.
  • Use group_vars/ and host_vars/ directories for clean variable management.
  • Patterns let you target flexible subsets of hosts (webservers:&production, all:!staging).
  • Use dynamic inventory plugins for cloud environments — hosts are discovered automatically.
  • Set a default inventory in ansible.cfg to avoid passing -i on every command.