Dynamic inventory plugins

Ansible · Expert · 10 min

In clouds, hosts come and go; static files are always out of date.

An inventory plugin generates hosts and groups at run time. You configure it with a YAML file whose name ends as the plugin expects (for example *.aws_ec2.yml) and whose plugin: key names it:

  • amazon.aws.aws_ec2, azure.azcollection.azure_rm, google.cloud.gcp_compute,
  • kubernetes.core.k8s, community.vmware.vmware_vm_inventory, netbox.netbox.nb_inventory.

Common options:

  • filters: which instances to include (running, tagged env: prod).
  • keyed_groups: create groups from attributes, e.g. a group per tags.role, so plays can target role_web.
  • groups: groups from Jinja2 conditions.
  • compose: set host variables from attributes (ansible_host: private_ip_address).
  • hostnames: what to call each host.
  • cache: true: avoid querying the API on every run.

The constructed plugin applies the same keyed_groups/groups/compose logic on top of any other inventory sources, and you can point -i at a directory that mixes static files and plugins; they're merged in alphabetical order.

Enable plugins with enable_plugins in [inventory] if you restrict them, and test with ansible-inventory -i inventory/ --graph.

Legacy executable inventory scripts that print JSON still work, but plugins are the supported mechanism.

Example

# inventory/prod.aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions: [eu-west-1]
filters:
  instance-state-name: running
  "tag:env": prod
hostnames: [tag:Name]
keyed_groups:
  - key: tags.role
    prefix: role
compose:
  ansible_host: private_ip_address
cache: true
cache_plugin: ansible.builtin.jsonfile
cache_connection: .inventory_cache
# ansible-inventory -i inventory/ --graph
# @all:
#   |--@aws_ec2:
#   |--@role_web:
#   |  |--web-prod-1

Remember

  • Plugins query APIs at run time: no stale host lists
  • keyed_groups, groups and compose shape groups and variables
  • constructed adds the same logic to any source; cache to save API calls

Watch out for

  • Naming the config file without the plugin's required suffix, so Ansible doesn't recognise it.

Check yourself

  1. How do you target all EC2 instances tagged role=web with the aws_ec2 plugin configuration above?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.ansible.com/ansible/latest/inventory_guide/intro_dynamic_inventory.html

Builds on

Unlocks

Nothing builds on this yet.