Previously we took a look at creating a basic plain text file inventory for our Ansible automation project, but we will need more functionality when we start using it seriously. Luckily Ansible provides us some other ways to create groups of hosts and handle them. Let’s investigate what else can we do in an Ansible inventory!
We have already created the simplest possible inventory, a file with a host entry. The possible simplest inventory file is an INI file containing our Ansible control node.
Ansible looks for the /etc/ansible/hosts
file for an inventory by default. We can provide the command line tools any inventory file with using the -i
option, like ansible-playbook -i hosts/inventory.ini
or any other file.
Let’s stay with the file-based inventories for now! We will take a look at the INI and YAML format.
Now it is time to understand how are the Ansible managed hosts grouped by default.
Default groups in Ansible inventories
Every host in an Ansible inventory will belong to two groups by default: all and ungrouped or a custom group.
The ansible-inventory
command will be in our help for exploring the groups.
$ ansible-inventory -i inventory --graph
@all:
|--@ungrouped:
| |--ansible-control
|--@vmware:
| |--@lab:
| | |--juiceshop
| |--@production:
| | |--kali
| | |--zoneminder
We can see from the example that every Ansible managed host is member of the all group.
The ansible-control host is not member of other custom groups, so this is automatically a member of the ungrouped group too.
The vmware is a non-default group, it was created by us in the INI file.
Inventory groups
We can create our own custom inventory groups:
[vmware]
test.vmware.host
In the INI format example we create a group called vmware and it contains the test.vmware.host host.
In YAML format it would look like this:
---
all:
children:
vmware:
hosts:
test.vmware.host:
An Ansible inventory can contain multiple groups, and a group can contain multiple hosts:
[vmware]
test.vmware
prod.vmware
staging.vmware
[hyperv]
test.hyperv
prod.hyperv
This INI inventory contains two groups (vmware and hyperv) and both contain multiple host entries.
The YAML format looks like this:
---
all:
children:
hyperv:
hosts:
prod.hyperv:
test.hyperv:
vmware:
hosts:
prod.vmware:
staging.vmware:
test.vmware:
Normally we want to group our hosts by some logic like function or location.
Groups of groups
Sometimes we want to handle groups in other groups. For example our vmware and hyperv groups are both virtualized host groups. We may want to create a parent group called virtual.
In this case the INI format will create the parent group with the :children
keyword after we created the child entries.
[vmware]
test.vmware
prod.vmware
staging.vmware
[hyperv]
test.hyperv
prod.hyperv
[virtual:children]
vmware
hyperv
Both groups are members of the virtual group now.
We can confirm it with the ansible-inventory
command:
$ ansible-inventory -i test.inventory.ini --graph
@all:
|--@ungrouped:
|--@virtual:
| |--@vmware:
| | |--test.vmware
| | |--prod.vmware
| | |--staging.vmware
| |--@hyperv:
| | |--test.hyperv
| | |--prod.hyperv
The YAML version of the same inventory looks like this:
---
all:
children:
virtual:
children:
hyperv:
hosts:
prod.hyperv:
test.hyperv:
vmware:
hosts:
prod.vmware:
staging.vmware:
test.vmware:
There are some things to remember about groups of groups in the Ansible documenation:
Ansible Documentation
- Any host that is member of a child group is automatically a member of the parent group.
- Groups can have multiple parents and children, but not circular relationships.
- Hosts can also be in multiple groups, but there will only be one instance of a host at runtime. Ansible merges the data from the multiple groups.
Converting the INI format to YAML
We can convert our INI format Ansible inventories to YAML with the ansible-inventory
command:
$ ansible-inventory -i test.inventory.ini --list --yaml
all:
children:
ungrouped: {}
virtual:
children:
hyperv:
hosts:
prod.hyperv: {}
test.hyperv: {}
vmware:
hosts:
prod.vmware: {}
staging.vmware: {}
test.vmware: {}
Listing the INI inventory and using the --yaml
option will print out the inventory in YAML format.
Behavioral inventory parameters
There are some behavioral parameters we can use in our inventory. They help us to fine-tune the connection and user settings for different hosts.
---
all:
children:
ansible:
hosts:
ansible-control:
ansible_become_method: sudo
ansible_connection: local
ansible_host: 192.168.3.130
vmware:
children:
lab:
hosts:
juiceshop:
ansible_become_method: su
ansible_become_user: root
ansible_host: 192.168.3.129
production:
hosts:
kali:
ansible_become_method: sudo
ansible_become_user: kali
ansible_host: 192.168.3.128
zoneminder:
ansible_become_method: su
ansible_become_user: root
ansible_host: 192.168.3.133
or
[ansible]
ansible-control ansible_host=192.168.3.130 ansible_become_method=sudo ansible_connection=local
[lab]
juiceshop ansible_host=192.168.3.129 ansible_become_method=su ansible_become_user=root
[production]
kali ansible_host=192.168.3.128 ansible_become_method=sudo ansible_become_user=kali
zoneminder ansible_host=192.168.3.133 ansible_become_method=su ansible_become_user=root
[vmware:children]
lab
production
Here is an example of the behavioral parameters we can use to control the connection, the users and so on. These options can be used in INI and YAML as well.
Here is a list of the parameters we can use in our inventory: https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html#connecting-to-hosts-behavioral-inventory-parameters
Other thoughts
We can pass variables or set host variables in our Ansible inventory though I found it problematic in big environments with a lot of hosts. It is even more difficult to track with dynamic inventory scripts mixed with static inventories.
When we want to run a playbook on an inventory of hosts, we can check the hosts beforehand with the ansible-playbook
command.
$ ansible-playbook -i inventory play-test.yml --list-hosts
playbook: play-test.yml
play #1 (all): Test playbook for playing with Ansible TAGS: []
pattern: ['all']
hosts (4):
kali
zoneminder
ansible-control
juiceshop
With the --list-hosts
option will show our host pattern in the playbook, and it lists the matched hosts.
It is also possible to narrow down the target hosts for a playbook with the --limit
option.
$ ansible-playbook -i inventory play-test.yml --limit ansible --list-hosts
playbook: play-test.yml
play #1 (all): Test playbook for playing with Ansible TAGS: []
pattern: ['all']
hosts (1):
ansible-control
It opens up a full world of possibilities for running Ansible of different target hosts and groups. Happy automating!
If you have anything to share then please visit my Tom’s IT Cafe Discord Server!