Open-Source Wikis

/

Ansible

/

Features

/

Dynamic inventory

ansible/ansible

Dynamic inventory

Inventory is "where Ansible learns about hosts and groups." It can be a static text file, an executable script, a YAML/INI/TOML file, or a structured cloud-aware plugin. All paths land in the same InventoryManager object that the executor consumes.

What an inventory describes

The data model is simple:

  • Hosts — named entries. Each host has its own variables.
  • Groups — collections of hosts. Each group has its own variables. Groups can contain other groups (children:).
  • The implicit all group — every host is in it.
  • The implicit ungrouped group — hosts not in any user-defined group.
  • Per-host and per-group variables — merged at runtime by VariableManager.

The Python representation:

Class File
InventoryManager lib/ansible/inventory/manager.py
InventoryData lib/ansible/inventory/data.py
Host lib/ansible/inventory/host.py
Group lib/ansible/inventory/group.py
Helpers lib/ansible/inventory/helpers.py

How an inventory source becomes hosts

graph TD
    SRC[Inventory source: file/dir/script/host list] --> MGR[InventoryManager]
    MGR --> AUTO[auto plugin: detect format]
    AUTO --> ENABLE[Walk INVENTORY_ENABLED list]
    ENABLE --> TRY[For each plugin: verify_file?]
    TRY -->|yes| PARSE[plugin.parse: populate InventoryData]
    TRY -->|no| NEXT[Try next plugin]
    NEXT --> ENABLE
    PARSE --> DATA[InventoryData: hosts, groups, vars]
    DATA --> MERGE[Merge across multiple sources]

InventoryManager.parse_sources() iterates over each user-supplied source (-i one -i two). For each source:

  1. Detect type. If the source is a text file, the auto plugin (lib/ansible/plugins/inventory/auto.py) inspects the first line to identify YAML/INI/TOML and delegates. If executable, it falls back to the script plugin. Comma-separated patterns dispatch to host_list or advanced_host_list.
  2. Walk enabled plugins. INVENTORY_ENABLED (default host_list, script, auto, yaml, ini, toml) lists candidate plugins. Each is asked verify_file(path) until one accepts.
  3. Parse. The accepting plugin's parse(inventory, loader, path) populates the InventoryData with hosts, groups, and per-entity vars.

Multiple sources merge: if -i a and -i b both define host1, both sets of variables apply (-i b later, so it overrides on conflict). Group memberships union.

Built-in inventory plugins

Plugin File Purpose
host_list lib/ansible/plugins/inventory/host_list.py Comma-separated hosts: -i 'h1,h2,h3' (the default test inventory)
advanced_host_list lib/ansible/plugins/inventory/advanced_host_list.py Range expansion: web[01:50].example.com
script lib/ansible/plugins/inventory/script.py Run an executable, parse its JSON --list and per-host --host <h> output
auto lib/ansible/plugins/inventory/auto.py Sniff the file format and dispatch
ini lib/ansible/plugins/inventory/ini.py Classic [group] section format
yaml lib/ansible/plugins/inventory/yaml.py YAML-formatted inventory
toml lib/ansible/plugins/inventory/toml.py TOML-formatted inventory
constructed lib/ansible/plugins/inventory/constructed.py Build new groups by templating against existing host vars
generator lib/ansible/plugins/inventory/generator.py Template hostnames against a list of values

Cloud-specific inventory plugins (AWS EC2, GCP, Azure, OpenStack, VMware, AWX) live in collections — amazon.aws.aws_ec2, google.cloud.gcp_compute, etc. They follow the same plugin contract.

Plugin interface

A custom inventory plugin (lib/ansible/plugins/inventory/__init__.py:BaseInventoryPlugin) implements two methods:

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

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

    def parse(self, inventory, loader, path, cache=True):
        super().parse(inventory, loader, path, cache)
        config = self._read_config_data(path)
        for host_data in self._fetch_hosts(config):
            inventory.add_host(host_data['name'], group=host_data['group'])
            for k, v in host_data['vars'].items():
                inventory.set_variable(host_data['name'], k, v)

The plugin can also implement update_cache_if_changed() and _read_config_data() to persist API results. Cache backends are the same as for facts (lib/ansible/plugins/cache/).

For YAML-configured plugins, the plugin's DOCUMENTATION block defines the schema; users supply a <name>.<plugin>.yml file with their config:

plugin: amazon.aws.aws_ec2
regions:
  - us-east-1
filters:
  tag:Environment: prod

ansible-inventory -i this.yml --graph runs the plugin and shows the resolved tree.

host_vars and group_vars

Adjacent to an inventory file, Ansible looks for host_vars/ and group_vars/ directories:

inventory.yml
host_vars/
  web01.yml
  web01.json
group_vars/
  webservers/
    main.yml
    secrets.yml
  all.yml

Picked up by the host_group_vars vars plugin (lib/ansible/plugins/vars/host_group_vars.py), not the inventory plugins themselves. Variables loaded here have a defined precedence relative to other sources — see lib/ansible/vars/manager.py:get_vars for the authoritative order.

--limit and patterns

Once parsed, InventoryManager.list_hosts(pattern) filters by host pattern. Patterns support:

  • Plain names: web01.
  • Group names: webservers.
  • Wildcards: web*.
  • Regex: ~web0[1-3].
  • Set algebra: webservers:!staging, webservers:&production.
  • Range subscript: webservers[0:10], webservers[-1].

--limit further restricts the host pattern. Patterns and limits are intersected.

ansible-inventory CLI

ansible-inventory (lib/ansible/cli/inventory.py) is the dedicated tool for inspecting what the inventory plugins resolve to:

ansible-inventory -i mycloud.yml --graph
ansible-inventory -i mycloud.yml --list             # JSON output (the dynamic inventory protocol)
ansible-inventory -i mycloud.yml --host web01.example.com
ansible-inventory -i mycloud.yml --toml

--list output follows the dynamic-inventory protocol — a stable JSON shape that other tools (Tower/AWX, Galaxy, third-party CMDBs) consume.

Integration points

  • Imported by: every CLI's __init__ via InventoryManager.
  • Plugins it loads: inventory_loader (the inventory plugins themselves), cache_loader (for caching expensive cloud queries), vars_loader (for host_group_vars).
  • Reads: the user-supplied source paths, plus host_vars//group_vars/ directories.
  • Output: an InventoryData consumed by VariableManager, PlayIterator, and the strategy plugins.

Entry points for modification

  • Adding a new inventory source — write a plugin extending BaseInventoryPlugin. Place it in a collection.
  • Changing pattern semanticslib/ansible/inventory/manager.py:_match_one_pattern. This code is sensitive; many users depend on the existing parse rules.
  • Per-host variable precedencelib/ansible/vars/manager.py:VariableManager.get_vars is the authoritative source. Don't change without carefully reading the docs and existing comments.

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

Dynamic inventory – Ansible wiki | Factory