Ansible Inventory: Static, Dynamic & Advanced Patterns (Complete Guide)
By Luca Berton · Published 2024-01-01 · Category: database-automation
Complete guide to Ansible inventory. Configure static INI and YAML inventories, dynamic inventory scripts, AWS/Azure/GCP plugins, host patterns, group.
The inventory defines what hosts Ansible manages and how to connect to them. It can be a simple INI file, YAML, a dynamic script pulling from cloud APIs, or a combination of all three.
Static Inventory (INI Format)
# inventory.ini
# Ungrouped hosts
mail.example.com
# Web servers
[webservers]
web1.example.com
web2.example.com
web3.example.com ansible_port=2222
# Database servers
[dbservers]
db1.example.com
db2.example.com
# Group of groups
[production:children]
webservers
dbservers
# Group variables
[webservers:vars]
http_port=80
ansible_user=deploy
[production:vars]
env=production
monitoring=true
Range Patterns
[webservers]
web[01:50].example.com # web01 through web50
[dbservers]
db-[a:f].example.com # db-a through db-f
See also: Learn Ansible: Complete Beginner's Guide & Learning Path (2026)
Static Inventory (YAML Format)
# inventory.yml
all:
children:
production:
children:
webservers:
hosts:
web1.example.com:
http_port: 80
web2.example.com:
http_port: 8080
vars:
ansible_user: deploy
dbservers:
hosts:
db1.example.com:
db_port: 5432
db2.example.com:
db_port: 5432
vars:
ansible_user: dbadmin
vars:
env: production
monitoring: true
staging:
children:
staging_web:
hosts:
staging-web1.example.com:
staging_db:
hosts:
staging-db1.example.com:
vars:
env: staging
Host and Group Variables
Directory Structure (Recommended)
inventory/
├── hosts.yml # Main inventory
├── group_vars/
│ ├── all.yml # Variables for ALL hosts
│ ├── webservers.yml # Variables for webservers group
│ ├── dbservers.yml # Variables for dbservers group
│ └── production/
│ ├── vars.yml # Production variables
│ └── vault.yml # Encrypted production secrets
└── host_vars/
├── web1.example.com.yml
└── db1.example.com.yml
# group_vars/all.yml
---
ntp_server: ntp.example.com
dns_servers:
- 8.8.8.8
- 8.8.4.4
# group_vars/webservers.yml
---
http_port: 80
max_connections: 1000
ssl_enabled: true
# host_vars/web1.example.com.yml
---
http_port: 8080 # Override for this host
ssl_cert: /etc/ssl/web1.pem
See also: Automate Text Capitalization with Ansible Playbooks
Dynamic Inventory
AWS EC2
# aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
- us-east-1
- eu-west-1
filters:
tag:Environment: production
instance-state-name: running
keyed_groups:
- key: tags.Role
prefix: role
- key: placement.region
prefix: aws_region
- key: instance_type
prefix: type
hostnames:
- tag:Name
- private-ip-address
compose:
ansible_host: private_ip_address
# Use dynamic inventory
ansible-playbook -i aws_ec2.yml site.yml
# Test / list hosts
ansible-inventory -i aws_ec2.yml --list
ansible-inventory -i aws_ec2.yml --graph
Azure
# azure_rm.yml
plugin: azure.azcollection.azure_rm
include_vm_resource_groups:
- production-rg
auth_source: auto
keyed_groups:
- key: tags.role | default('untagged')
prefix: role
- key: location
prefix: azure_region
hostnames:
- name
- private_ipv4_addresses
GCP
# gcp_compute.yml
plugin: google.cloud.gcp_compute
projects:
- my-gcp-project
zones:
- us-central1-a
- us-east1-b
filters:
- status = RUNNING
auth_kind: serviceaccount
service_account_file: /path/to/sa.json
keyed_groups:
- key: labels.env
prefix: env
Custom Script
#!/usr/bin/env python3
# custom_inventory.py
import json
import sys
def get_inventory():
return {
"webservers": {
"hosts": ["web1.example.com", "web2.example.com"],
"vars": {"http_port": 80}
},
"dbservers": {
"hosts": ["db1.example.com"],
"vars": {"db_port": 5432}
},
"_meta": {
"hostvars": {
"web1.example.com": {"ansible_host": "10.0.0.1"},
"web2.example.com": {"ansible_host": "10.0.0.2"},
"db1.example.com": {"ansible_host": "10.0.0.10"}
}
}
}
if __name__ == '__main__':
if '--list' in sys.argv:
print(json.dumps(get_inventory(), indent=2))
elif '--host' in sys.argv:
print(json.dumps({}))
chmod +x custom_inventory.py
ansible-playbook -i custom_inventory.py site.yml
Multiple Inventory Sources
# Combine static + dynamic
ansible-playbook -i inventory/static.yml -i inventory/aws_ec2.yml site.yml
# Use inventory directory
ansible-playbook -i inventory/ site.yml # Reads all files in directory
See also: Ansible AWS EC2: Automate Ubuntu Instance Creation & Data Collection
Host Patterns
# All hosts
ansible all -m ping
# Specific group
ansible webservers -m ping
# Multiple groups (OR)
ansible 'webservers:dbservers' -m ping
# Intersection (AND)
ansible 'webservers:&production' -m ping
# Exclusion (NOT)
ansible 'production:!dbservers' -m ping
# Wildcards
ansible 'web*.example.com' -m ping
# Regex
ansible '~web[0-9]+\.example\.com' -m ping
# Specific host
ansible web1.example.com -m ping
# Index
ansible 'webservers[0]' -m ping # First host
ansible 'webservers[-1]' -m ping # Last host
ansible 'webservers[0:3]' -m ping # First 3 hosts
Useful Commands
# List all hosts
ansible-inventory -i inventory.yml --list
# Show host graph
ansible-inventory -i inventory.yml --graph
# Show vars for a host
ansible-inventory -i inventory.yml --host web1.example.com
# Verify connectivity
ansible all -i inventory.yml -m ping
# Run ad-hoc command
ansible webservers -i inventory.yml -m command -a "uptime"
Best Practices
Use YAML format — more readable than INI for complex inventories Usegroup_vars/ and host_vars/ — separate variables from host lists
Encrypt secrets with Vault — group_vars/production/vault.yml
Use dynamic inventory for cloud — keeps inventory in sync automatically
Tag-based grouping — use keyed_groups with cloud tags
One source of truth — don't duplicate hosts across files
Test with ansible-inventory --graph — verify structure before running
FAQ
What is Ansible inventory?
The inventory is a file or script that lists the hosts Ansible manages, organized into groups. It defines connection parameters (IP, user, port) and variables. It can be a static file (INI/YAML) or dynamic (pulling from AWS, Azure, etc.).
What is the difference between static and dynamic inventory?
Static inventory is a manually maintained file (INI or YAML). Dynamic inventory is a script or plugin that queries an external source (cloud API, CMDB, LDAP) at runtime to generate the host list automatically.
Where is the default inventory file?
/etc/ansible/hosts is the default. Override with -i inventory.yml on the command line or inventory = ./inventory.yml in ansible.cfg.
How do I use group variables?
Create group_vars/ files next to your inventory. Variables defined there automatically apply to all hosts in that group. Use group_vars/all.yml for variables that apply everywhere.
How do I test if inventory is working?
Run ansible-inventory -i inventory.yml --graph to see the host structure, then ansible all -i inventory.yml -m ping to test connectivity.
Conclusion
• INI or YAML — YAML preferred for complex inventories •group_vars/ + host_vars/ — organize variables cleanly
• Dynamic inventory plugins — AWS, Azure, GCP, VMware
• Host patterns — webservers:&production:!dbservers for precise targeting
• ansible-inventory --graph — always verify your inventory structure
Related Articles
• Ansible Playbook Structure & Best Practices • Ansible Variable Precedence Guide • Ansible AWS Cloud Automation GuideCategory: database-automation