Stage 4 · Provision
Dynamic Inventory & Scale
Dynamic Inventory
Inventory plugins for AWS, Azure, and GCP with auto-discovery.
Why Dynamic Inventory?
Static inventory files become outdated as cloud instances are created and destroyed. Dynamic inventory plugins query cloud providers or APIs to discover hosts in real time. Ansible always knows what exists.
AWS EC2 Inventory
---
plugin: amazon.aws.aws_ec2
regions:
- us-east-1
- us-west-2
filters:
tag:Environment: production
instance-state-name: running
keyed_groups:
- key: tags.Role
prefix: role
separator: "_"
- key: placement.availability_zone
prefix: az
- key: instance_type
prefix: type
compose:
ansible_host: private_ip_address
ansible_user: "'ec2-user'"
hostnames:
- private-ip-address
- tag:NameThe aws_ec2 plugin discovers EC2 instances and groups them by tags, AZ, or instance type. Compose maps instance attributes to Ansible variables.
Azure Inventory
---
plugin: azure.azcollection.azure_rm
source:
subscription_id: "{{ azure_subscription_id }}"
tenant: "{{ azure_tenant_id }}"
resource_groups:
- production-webservers
- production-dbservers
plain_host_names: yes
keyed_groups:
- key: tags.Role
prefix: role
- key: location
prefix: location
compose:
ansible_host: private_ip
ansible_user: "'adminuser'"Azure inventory plugin discovers VMs by resource group. Tags define host groups automatically.
Custom Inventory Scripts
#!/usr/bin/env python3
import json
import sys
import argparse
def get_inventory():
inventory = {
"_meta": {"hostvars": {}},
"webservers": {
"hosts": ["web1.example.com", "web2.example.com"],
"vars": {"http_port": 80}
},
"dbservers": {
"hosts": ["db1.example.com"],
"vars": {"db_port": 5432}
}
}
return json.dumps(inventory)
def get_host(hostname):
hostvars = {
"web1.example.com": {"ansible_host": "10.0.1.10"},
"web2.example.com": {"ansible_host": "10.0.1.11"},
"db1.example.com": {"ansible_host": "10.0.2.10"}
}
return json.dumps(hostvars.get(hostname, {}))
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--list", action="store_true")
parser.add_argument("--host", type=str)
args = parser.parse_args()
if args.list:
print(get_inventory())
elif args.host:
print(get_host(args.host))Inventory scripts must support --list (all hosts) and --host (single host). Return JSON with _meta for host variables.
Testing Inventory Plugins
# List all hosts
ansible-inventory -i aws_ec2.yml --list
# Show host graph
ansible-inventory -i aws_ec2.yml --graph
# Show variables for a host
ansible-inventory -i aws_ec2.yml --host web1.example.com
# Test plugin directly
ansible-inventory -i aws_ec2.yml --yamlUse ansible-inventory to verify your dynamic inventory plugin returns the expected hosts and groups before running playbooks.
Dynamic inventory queries can be slow. Enable caching in ansible.cfg with inventory_cache_refresh to avoid repeated API calls during development.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.