Inventory Management
Relevant source files
The following files were used as context for generating this wiki page:- lib/ansible/inventory/manager.py
- lib/ansible/inventory/host.py
- lib/ansible/inventory/group.py
- lib/ansible/plugins/inventory/ini.py
- lib/ansible/inventory/data.py
- lib/ansible/plugins/inventory/script.py
- lib/ansible/plugins/inventory/yaml.py
- lib/ansible/plugins/inventory/constructed.py
- lib/ansible/plugins/inventory/generator.py
Inventory management is the system within Ansible that defines and organizes the managed nodes (hosts) that automation tasks are executed against. It provides a flexible, plugin-based architecture for loading hosts and their associated data from various sources, such as static files (INI, YAML) or dynamic scripts. The core purpose is to create an in-memory representation of the infrastructure, allowing users to select and group hosts for targeted playbook execution.
The central component of this system is the InventoryManager, which orchestrates the parsing of inventory sources and provides an interface for querying hosts and groups. It relies on a set of data structures, primarily Host and Group objects, which are held within an InventoryData container. This system is fundamental to Ansible's operation, as it determines the targets for all automation.
Sources: lib/ansible/inventory/manager.py, lib/ansible/inventory/data.py, README.md:14-18
Core Components
The inventory system is built around a few key classes that model the infrastructure and manage the data.
Sources: lib/ansible/inventory/manager.py, lib/ansible/inventory/data.py, lib/ansible/inventory/host.py, lib/ansible/inventory/group.py
Class Diagram
The following diagram illustrates the primary classes and their relationships within the inventory management system.
InventoryManager
The InventoryManager is the main entry point and orchestrator for inventory operations. It is initialized with a loader and a list of inventory sources. Its primary responsibilities include:
- Parsing inventory sources by iterating through them and invoking the appropriate inventory plugins.
- Holding a reference to the
InventoryDataobject that stores all host and group information. - Providing methods like
get_hosts()to query the inventory using patterns. - Managing restrictions and subsets (
--limit). - Caching resolved host patterns for performance.
Sources: lib/ansible/inventory/manager.py:109-129
InventoryData
This class acts as the primary data container for the inventory. It holds dictionaries of all Host and Group objects.
Key features:
- Initializes with two default groups:
allandungrouped. Theungroupedgroup is a child ofall. - Provides methods to add hosts (
add_host), groups (add_group), and establish parent-child relationships (add_child). - The
reconcile_inventory()method is called after parsing to enforce inventory rules, such as ensuring all groups are descendants ofalland placing hosts without explicit group membership intoungrouped. - Manages an implicit
localhosthost if one is not explicitly defined.
Sources: lib/ansible/inventory/data.py:32-50, 78-112
Host
A Host object represents a single managed node in the inventory. Each host has:
- A unique
name. - An
addressused for connection. - A dictionary of
varsassociated with it. - A list of groups it belongs to.
Variables can be assigned to a host using the set_variable() method.
Sources: lib/ansible/inventory/host.py
Group
A Group object is a collection of hosts and/or other groups (children). This allows for a hierarchical organization of the inventory. Each group has:
- A unique
name. - A dictionary of
varsthat apply to all hosts within it. - Methods to add hosts (
add_host) and child groups (add_child_group). - The ability to trace its lineage through
get_ancestors().
The system pre-defines two essential groups:
all: A root group that contains every host in the inventory.ungrouped: A group for hosts that are not assigned to any other group. It is a child ofall.
Sources: lib/ansible/inventory/group.py, lib/ansible/inventory/data.py:47-50
Inventory Parsing Process
The InventoryManager is responsible for parsing various inventory sources and populating the InventoryData object. This process is plugin-driven, allowing for great flexibility in how inventory is defined.
Sources: lib/ansible/inventory/manager.py:180-288
Parsing Flow
The diagram below shows the high-level flow of parsing an inventory source.
This diagram shows how InventoryManager iterates through sources, handling directories recursively and using a series of plugins to attempt parsing for each file or string source.
Sources: lib/ansible/inventory/manager.py:180-288
Plugin Selection and Execution
- Plugin Loading: The
_fetch_inventory_pluginsmethod retrieves all enabled inventory plugins as defined in theansible.cfgINVENTORY_ENABLEDsetting. - Verification: For each source, the
InventoryManageriterates through the loaded plugins. It calls theverify_file(source)method on each plugin. The first plugin to returnTrueis chosen to parse that source. - Parsing: The selected plugin's
parse()method is called. This method receives theInventoryDataobject (via a wrapper), the loader, and the source path. The plugin is responsible for reading the source and usinginventory.add_host(),inventory.add_group(), andinventory.set_variable()to populate the inventory. - Wrapper for Trust: The
parsemethod is passed an_InventoryDataWrapperinstead of the rawInventoryDataobject. This wrapper intercepts calls toset_variableand, based on the plugin'strusted_by_defaultattribute, can automatically apply template trust to variable values. - Reconciliation: After all sources are parsed,
_inventory.reconcile_inventory()is called to finalize relationships, assign hosts to theungroupedgroup if necessary, and perform other cleanup tasks.
Sources: lib/ansible/inventory/manager.py:168-178, 222-254, 599-621
Inventory Plugins
Ansible uses a plugin system to support various inventory formats. Each plugin is a class that inherits from BaseInventoryPlugin and implements methods for verification and parsing.
| Plugin | File Extension(s) | Description | Source File |
|---|---|---|---|
ini | .ini, (none) | Parses classic INI-style inventory files. Sections define groups, and hosts are listed within them. Vars can be defined for hosts inline or in [group:vars] sections. | lib/ansible/plugins/inventory/ini.py |
yaml | .yaml, .yml, .json | Parses YAML-formatted files. Top-level keys are group names, with nested hosts, vars, and children keys. | lib/ansible/plugins/inventory/yaml.py |
script | (executable file) | Executes a script that returns inventory data as JSON. The script must support --list and --host <hostname> arguments. | lib/ansible/plugins/inventory/script.py |
constructed | .config, .yml, .yaml | Does not add new hosts, but constructs new groups and variables from existing inventory data using Jinja2 expressions. | lib/ansible/plugins/inventory/constructed.py |
generator | .config, .yml, .yaml | Generates a cartesian product of hosts and groups from layered templates. | lib/ansible/plugins/inventory/generator.py |
Dynamic Inventory with script
The script plugin allows for fully dynamic inventories. An inventory script is an executable that, when called with the --list argument, must output a JSON object representing the entire inventory.
A key performance optimization is the _meta key in the JSON output. If _meta.hostvars is present, Ansible will use it to populate all host variables at once, avoiding a separate call to the script with --host <hostname> for each host.
Example JSON output structure:
{
"all": {
"vars": {
"global_var": "value"
}
},
"webservers": {
"hosts": [
"web1.example.com",
"web2.example.com"
]
},
"_meta": {
"hostvars": {
"web1.example.com": {
"http_port": 80
},
"web2.example.com": {
"http_port": 8080
}
}
}
}
Sources: lib/ansible/plugins/inventory/script.py:14-22, 168-176
Data Model and Relationships
The inventory data model is a graph structure composed of hosts and groups.
This diagram shows that a host can be a member of many groups, and a group can contain many hosts (a many-to-many relationship). Furthermore, a group can be a child of many parent groups, and a group can have many child groups, forming a directed acyclic graph.
- Hosts and Groups: A
Hostcan belong to multipleGroups. This relationship is established bygroup.add_host(host). - Group Hierarchy: A
Groupcan have otherGroups as children. This is established byparent_group.add_child_group(child_group). All groups are implicitly or explicitly children of theallgroup.
Sources: lib/ansible/inventory/data.py:182-200, 235-247, lib/ansible/inventory/group.py:120-132
Host and Group Querying
Once the inventory is parsed, the InventoryManager provides a powerful mechanism for selecting hosts using patterns.
get_hosts() Method
The primary method for querying is get_hosts(pattern="all", ...). It takes a pattern string (or list of strings) and returns a list of matching Host objects.
Sources: lib/ansible/inventory/manager.py:382-388
Pattern Matching
Patterns are evaluated in a specific order to produce the final host list.
- Regular Patterns: Patterns without a prefix (e.g.,
webservers,db*) are evaluated first. Their results are added to the list of hosts. - Intersection (
&): Patterns prefixed with&(e.g.,®ion_east) filter the current list of hosts, keeping only those that also match the intersection pattern. - Exclusion (
!): Patterns prefixed with!(e.g.,!staging) filter the current list, removing any hosts that match the exclusion pattern.
If no regular pattern is provided, all is used as the default starting set.
Sources: lib/ansible/inventory/manager.py:137-162, 428-448
Subscripting
Patterns can include a subscript to select a slice or a single host from the matched set. This is only applied if the pattern matches one or more groups.
webservers[0]: Selects the first host in thewebserversgroup.webservers[1:3]: Selects the second through fourth hosts (inclusive).
Sources: lib/ansible/inventory/manager.py:476-492, 509-524
Conclusion
Ansible's inventory management system is a robust and extensible framework for defining the targets of automation. At its core, the InventoryManager uses a plugin-based architecture to parse diverse sources into a consistent in-memory graph of Host and Group objects stored in InventoryData. This structure allows for complex hierarchical organization and variable inheritance. Finally, a powerful pattern-matching and querying engine gives users fine-grained control over which hosts a playbook will run against, making it a cornerstone of Ansible's flexibility.