Open-Source Wikis

/

Ansible

/

Plugins

/

Inventory plugins

ansible/ansible

Inventory plugins

Inventory plugins resolve a source (a text file, an executable, a YAML config pointing at a cloud API) to a population of hosts and groups. ansible-core ships nine plugins in lib/ansible/plugins/inventory/.

Files

lib/ansible/plugins/inventory/
├── __init__.py              # BaseInventoryPlugin and BaseFileInventoryPlugin
├── advanced_host_list.py    # Range expansion: web[01:50].example.com
├── auto.py                  # Sniff format, dispatch to the right plugin
├── constructed.py           # Build new groups by templating against host vars
├── generator.py             # Generate hostnames by interpolating into a list
├── host_list.py             # Comma-separated hosts: 'h1,h2,h3'
├── ini.py                   # Classic [group] section format
├── script.py                # Run an executable, parse JSON
├── toml.py                  # TOML inventory
└── yaml.py                  # YAML inventory

The cloud-aware plugins (AWS EC2, GCP, Azure, OpenStack, VMware, AWX, Foreman, Netbox, etc.) live in collections.

BaseInventoryPlugin

lib/ansible/plugins/inventory/__init__.py:BaseInventoryPlugin is the abstract base. The contract:

Method Purpose
verify_file(path) Predicate: is this source mine?
parse(inventory, loader, path, cache=True) Populate the InventoryData
get_cache_key(path) Cache namespace if the plugin uses caching
_read_config_data(path) Read the YAML config and validate against DOCUMENTATION schema

BaseFileInventoryPlugin is a thin convenience subclass for plugins whose source is a single file.

A typical custom plugin

class InventoryModule(BaseInventoryPlugin):
    NAME = 'mycorp.cloud'

    def verify_file(self, path):
        return path.endswith(('.mycorp.yml', '.mycorp.yaml'))

    def parse(self, inventory, loader, path, cache=True):
        super().parse(inventory, loader, path)
        config = self._read_config_data(path)

        for host in self._fetch_inventory(config):
            inventory.add_host(host['name'], group=host['group'])
            for k, v in host['vars'].items():
                inventory.set_variable(host['name'], k, v)

        for group, children in self._compute_groups(config).items():
            inventory.add_group(group)
            for child in children:
                inventory.add_child(group, child)

The plugin's top-of-file DOCUMENTATION declares the YAML schema, including any options the user can set in the inventory config:

---
name: mycloud
plugin_type: inventory
short_description: My Cloud inventory source
options:
  api_url:
    description: API endpoint
    type: str
    required: true
  region:
    type: str
    default: us-east-1
extends_documentation_fragment:
  - constructed
  - inventory_cache

The two extends_documentation_fragment entries are common — they bring in standard groups, keyed_groups, compose (from the constructed fragment, see below) and cache/cache_plugin/cache_timeout (from inventory_cache).

Built-in plugins

host_list

The simplest. Parses comma-separated host lists from -i 'h1,h2,h3'. Used by tests and ad-hoc invocations:

ansible all -i 'web1.example.com,web2.example.com,' -m ping

The trailing comma is required when there's a single host, to disambiguate from a file path.

advanced_host_list

Range expansion:

web[01:50].example.com:22 ansible_user=ec2-user
db[a:f].example.com

The [01:50] syntax expands to web01, web02, ..., web50. [a:f] expands to a, b, ..., f.

script

Runs an executable inventory provider. The script must respond to:

  • --list — JSON dump of every group's hosts and variables.
  • --host <name> — JSON dump of one host's variables.

This is the legacy "dynamic inventory script" interface, predating inventory plugins. Many cloud-inventory tools still ship as scripts even when an equivalent plugin exists.

auto

Inspects a file's first line and dispatches:

  • plugin: <name> → use the named plugin (a YAML config file calling a cloud plugin).
  • Looks like INI → ini plugin.
  • Looks like YAML → yaml plugin.
  • Looks like TOML → toml plugin.
  • Looks like a host pattern → host_list or advanced_host_list.
  • Executable → script plugin.

This is what makes ansible-playbook -i inventory "just work" — the user doesn't have to specify which plugin to use.

ini, yaml, toml

The three static-file formats:

  • ini — the classic [webservers] / [webservers:vars] / [webservers:children] format.
  • yaml — same data model in YAML, with hosts/groups/vars/children as dict keys.
  • toml — same data model in TOML.

All three populate the same InventoryData object. Choice is taste; INI is most common in older deployments, YAML in newer ones.

constructed

The most interesting non-cloud plugin. constructed doesn't fetch any new hosts; it adds groupings and computed variables to existing hosts based on host facts:

plugin: constructed
groups:
  is_red_hat: "ansible_distribution == 'RedHat'"
  is_aws: "'amazonaws' in ansible_default_ipv4.address|string"
keyed_groups:
  - prefix: env
    key: env
  - prefix: region
    key: ansible_default_ipv4.gateway | regex_replace(...)
compose:
  ansible_host: ansible_default_ipv4.address

After processing, the inventory has is_red_hat and env_prod/env_staging groups, and every host has ansible_host overridden to its primary IPv4 address.

The same machinery is exposed to other inventory plugins via the constructed doc fragment — set those keys and BaseInventoryPlugin._set_composite_vars/_add_host_to_keyed_groups/_add_host_to_composed_groups will do the work.

generator

Emits hostnames by interpolating against a list:

plugin: generator
hosts:
  name: '{{ application }}-{{ environment }}-{{ instance }}'
  parents:
    - name: '{{ application }}'
    - name: '{{ environment }}'
    - name: '{{ instance }}'
layers:
  application: [api, web, worker]
  environment: [prod, staging]
  instance: [01, 02, 03]

Useful when you need to generate a deterministic-named host fleet without listing them by hand.

Caching

Cloud-aware plugins are typically slow (an API call per refresh). The inventory_cache doc fragment plus lib/ansible/plugins/cache/ provide the usual backends:

plugin: amazon.aws.aws_ec2
cache: true
cache_plugin: jsonfile
cache_connection: ~/.ansible/inventory_cache
cache_timeout: 3600

The cache_plugin can be any cache plugin (memory, jsonfile, or collection-supplied like community.general.redis).

Multiple inventory sources

-i a -i b parses each in order. The result merges:

  • A host present in both sources gets the union of variables (later sources override on conflict).
  • A group present in both sources gets the union of hosts and the union of variables.
  • Group child relationships union.

Inventory directories are walked recursively; each readable file is parsed.

Integration points

  • Imported by: lib/ansible/inventory/manager.py:InventoryManager via inventory_loader.get.
  • Loaded for: every CLI that uses -i, including ansible-inventory, ansible-playbook, ansible, ansible-pull, ansible-console.
  • Order of plugin attempts: INVENTORY_ENABLED config option (default: host_list, script, auto, yaml, ini, toml).

Entry points for modification

  • A new cloud inventory — write a plugin in a collection. Subclass BaseInventoryPlugin. Implement verify_file and parse. Use the constructed and inventory_cache doc fragments for free composed-groups and caching support.
  • A new built-in static format — would belong in lib/ansible/plugins/inventory/. Rare; the existing three static formats cover most needs.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Inventory plugins – Ansible wiki | Factory