Updated April 10, 2023
Introduction to Ansible Dynamic Inventory
The following article provides an outline for Ansible Dynamic Inventory. Ansible need inventory files to get target nodes information for running tasks or plays on them. The inventory file can be static or dynamic. We know very well that using static inventories are not realistic in production environment mostly. Because static files are managed manually, but in real, the infrastructure environments keep changing continuously very frequently. We always create new nodes and removes unwanted nodes, this practice is very common and done frequently, especially in cloud and container environments. So in such cases, we need Dynamic Inventory, which fetches the list of nodes from infrastructure environment in real time based on some criteria.
What is Ansible Dynamic Inventory?
For the business requirements, we need to create, remove and modify the hosts in our infrastructure environment very frequently and to manage those nodes via Ansible, one need to update the inventory file very frequently. So, static inventory file is not suitable. In such case, we need an inventory file which updates itself.
This type of inventory file is called Dynamic inventory file, which have dynamic contents. In our environment, the sources of host nodes can be AWS, OpenStack, Cobbler, LDAP systems. These systems have their list of nodes and Ansible supports to integrates such external dynamic inventory.
In Ansible we have two ways to connect to external dynamic inventories:
- Via Scripts: This is the older way and ensures backward compatibility. But don’t use it with latest versions.
- Using Plugins: This is recommended over scripts for dynamic inventory, as plugins are updated with Ansible core code to take advantage of it.
Along with these two, if someone wants to use GUI, then RedHat Ansible Tower or free version of AWX can be used, these integrates with the source of remote hosts and provides a nice view with graphical inventory editor.
How does Ansible Dynamic Inventory works?
In Ansible, Dynamic inventory is generated either by scripts which are written in a programming language like python, php etc. or using available inventory plugins. When using script, they gets all real time data from the target source environments, like Cloud platforms AWS, OpenStack, GCP etc. Ansible community have already developed such kind of scripts for majority of platforms like AWS, OpenStack, GCP. Such kind of scripts can be written by you as well. But using scripts is not very well documented and not successful every time when using script, we must download the scripts for source environment and set env variable as per that.
These scripts are maintained by Ansible community. Mostly the scripts are written in python and named as ec2.py, open-stack_inventory.py. Along with these python scripts there are ini files as well which are needed to set the environment. But this is completely dependent on the script you are using. In Ansible, we have a set of available inventory plugins which are packed with Ansible packages. Similarly you can create your own plugins which suits your requirements and source of remote nodes. The inventory returns the list of items in JSON format. Ansible provides a bunch of inventory plugins using which you can use to get the list of target hosts, on which you will be running any task or play.
Using below command you can get the list of available inventory plugins:
Code:
ansible-doc -t inventory -l
From that list you can select the plugin which is reasonable for your source environment.
Then you can get details or documentation about that plugin using command like below:
Code:
ansible-doc -t inventory <plugin name>
Below is the list of inventory plugins available to Ansible 2.9.7. This is list may get updated in future versions of Ansible.
- nmap
- host_list
- hcloud
- openstack
- vultr
- aws_ec2
- cloudscale
- virtualbox
- constructed
- k8s
- generator
- script
- vmware_vm_inventory
- linode
- docker_machine
- yaml
- online
- azure_rm
- docker_swarm
- advanced_host_list
- foreman
- auto
- kubevirt
- gitlab_runners
- netbox
- gcp_compute
- aws_rds
- openshift
- toml
- tower
- scaleway
- ini
To use a plugin you have to enable it, by default in ansible.cfg we have enable_plugins parameter defining it. Also auto is set default to it which identifies the right plugin to parse based on provided files.
But to enable a specific inventory plugin, you must give fully qualified name of it like below in ansible.cfg.
Code:
[inventory]
enable_plugins = namespace.collection_name.inventory_plugin_name
After enabling a plugin, we must provide an inventory source to system to parse it. This is a file in same relative path to inventory or playbook.
Examples of Ansible Dynamic Inventory
Given below are the examples of ansible dynamic inventory:
As this is an advance feature in Ansible, we will use a very useful and common inventory plugin named aws_ec2.
Example #1
For this we create a source file named demo_aws_ec2.yaml. which have below contents.
Code:
plugin: aws_ec2 regions:
ap-south-1 filters:
tag:tagtype: testing
Also, we need to set and export at least below env variables for making connection with AWS environment.
The values give to these are Access Key ID and Secret Access Key of your account.
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
Once above is completed, you must have below requirements on your Ansible controller node:
- Boto3
- botocore
Now, in our environment, we have EC2 instances tagged differently.
We try to get list of same using tags like below:
Code
ansible-inventory -i demo_aws_ec2.yaml –graph
Output:
We will get output like below, because we have only one ec2 instance which have one tag matching to our source file:
Example #2
Now we update this source file like below to use private ipv4 address of matched EC2 instances:
Code:
plugin: aws_ec2 regions:
ap-south-1 filters:
tag:tagtype: testing compose:
ansible_host: private_ip_address
We have a sample playbook to create a file on target node with contents like below:
Code:
hosts:
all tasks:
name: here we create a file on target nodes file:
state: touch
path: /var/tmp/from_dyn_inv.txt
Code:
ansible-playbook ansible_dyn_inv.yaml -i demo_aws_ec2.yaml -v
Output:
Example #3
Now when we have another EC2 with matching condition of source file like same tag, ideally the playbook should now automatically run on that hosts as well.
First check the list of matching EC2 instances like below after updating the tag value of another EC2 instance:
Code:
ansible-inventory -i demo_aws_ec2.yaml --graph
Output:
Example #4
Now when we run the same playbook on this inventory, sample file will be created on both hosts.
Code:
ansible-playbook ansible_dyn_inv.yaml -i demo_aws_ec2.yaml -v
Output:
Conclusion
We saw that using and setting up Ansible Dynamic Inventories is a complex task and dependent on the environments for which you set it up. But once the setup is completed and we start getting real time list of target nodes, then you can at least take away the task of updating inventories from your daily task’s checklist.
Recommended Articles
This is a guide to Ansible Dynamic Inventory. Here we discuss the introduction, what is ansible dynamic inventory? how does ansible dynamic inventory works? and examples. You may also have a look at the following articles to learn more –