AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

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 Use group_vars/ and host_vars/ — separate variables from host lists Encrypt secrets with Vaultgroup_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/.yml 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 patternswebservers:&production:!dbservers for precise targeting • ansible-inventory --graph — always verify your inventory structure

Related Articles

Ansible Playbook Structure & Best PracticesAnsible Variable Precedence GuideAnsible AWS Cloud Automation Guide

Category: database-automation

Browse all Ansible tutorials · AnsiblePilot Home