This article explores dynamic inventory files in Ansible, comparing them with static inventories and detailing their benefits and implementation.
In this article, we explore how dynamic inventory files work in Ansible and highlight the differences between dynamic and static inventories. Traditionally, you might have used a static inventory file—manually created with hostnames, IP addresses, and grouping details. For example, a basic static inventory file in INI format would look like this:
This static approach works well for small setups with just a few servers. However, when managing large environments with hundreds or thousands of servers—whether on-premise or in the cloud—the manual upkeep of a static inventory becomes impractical, especially when servers are frequently provisioned or decommissioned.
Dynamic inventory allows Ansible to programmatically retrieve host and group data at runtime by querying external sources, such as CMDBs or cloud provider APIs. This eliminates the need for manual updates, ensuring that your inventory stays current.
Converting a Static Inventory to a Dynamic Inventory Script
Assume you have a static inventory as shown above. To convert it into a dynamic inventory, you can create a Python script—say, inventory.py—that outputs the inventory data in JSON format. You can then run your playbook with either the static file or the dynamic script:
If the --host argument is passed, the script should return the specific host’s variables in JSON format. Although this example is basic, it effectively demonstrates the concept of a dynamic inventory in Ansible. In production environments, you might enhance the script to fetch live inventory data from a CMDB or cloud service API.
In certification exams, you are not typically required to write such inventory scripts. However, you should understand how these scripts function and supply inventory data to Ansible.
Dynamic inventory is especially useful when managing cloud instances. For instance, to manage AWS instances, you can use the EC2 inventory script. After downloading the ec2.py script from the Ansible GitHub repository, run your playbook with the following command:
Copy
Ask AI
$ ansible-playbook playbook.yml -i ec2.py
Since the script interacts with AWS, you must authenticate first. A common method is to export your AWS credentials:
In addition to static (INI) and dynamic (Python script) inventories, Ansible also supports YAML inventory files. For example, the same inventory data can be expressed in YAML as follows:
Ansible uses various inventory plugins to process these different formats:
INI plugin: Reads inventory data from INI files.
Script plugin: Executes a script and interprets its JSON output as inventory.
YAML plugin: Interprets YAML-formatted files.
These plugins are essentially Python scripts working in the background, and Ansible’s extensible design even allows you to write your own plugins for custom data sources (e.g., XML).You can control which inventory plugins are active via the Ansible configuration file, typically located at /etc/ansible/ansible.cfg, under the [inventory] section:
Copy
Ask AI
[inventory]enable_plugins = host_list, script, auto, yaml, ini
While the dynamic inventory script is a tried-and-true method, Ansible now recommends using inventory plugins. Although inventory scripts are simple and can be implemented in any language, inventory plugins offer better integration with the Ansible ecosystem and additional functionality.Consider the following example of an advanced dynamic inventory script written in Python:
Here’s an excerpt showcasing how an inventory plugin might extend Ansible’s functionality:
Copy
Ask AI
from __future__ import absolute_import, division, print_function__metaclass__ = typeimport hashlibimport osimport stringfrom ansible.errors import AnsibleError, AnsibleParserErrorfrom ansible.inventory.group import to_safe_group_name as original_safefrom ansible.parsing.utils.addresses import parse_addressfrom ansible.plugins import AnsiblePluginfrom ansible.plugins.cache import CachePluginAdjudicator as CacheObjectfrom ansible.module_utils._text import to_bytes, to_nativedisplay = Display()def expand_hostname_range(line=None): if line: # Example: Replace delimiters and split to get numeric bounds line = line.replace('!', '|').replace('|', ' ').split('|') bounds = [int(x) for x in line] if len(bounds) not in (2, 3): raise AnsibleError("Host range must be in the format begin:end or begin:end:step")
This example demonstrates that while you can create a basic dynamic inventory with a standalone script, inventory plugins offer a more robust, integrated solution for advanced use cases.
Debugging your inventory configuration is simple with the ansible-inventory command. This utility displays how Ansible interprets your inventory data. For example, when testing the EC2 inventory script, you might run:
Using the ansible-inventory command is an excellent way to troubleshoot issues with inventory variables and to ensure that your dynamic inventory is working as expected.
That concludes our exploration of dynamic inventory in Ansible. Experiment with both static and dynamic inventories to find the best approach for your environment, and leverage Ansible’s extensive inventory plugins for a streamlined and scalable automation experience.