Every Ansible task runs against an inventory. An Inventory is a list of hosts that you wish to run an automation task on. In this tutorial, I will explain what inventory is and what are different inventory formats.
What is Ansible Inventory?
Ansible inventory is an important component while managing and orchestrating IT infrastructure. It serves as a source of truth for Ansible, enabling you to define the hosts and groups of hosts that Ansible can manage.
Ansible inventory is a file or set of files that contain information about the nodes or hosts that Ansible can manage. This includes IP addresses, FQDNs (Fully Qualified Domain Names), aliases, variables, and groupings of hosts. With this information, Ansible understands the infrastructure it needs to configure and the tasks it needs to accomplish. Ansible supports wide range of inventory formats which includes dynamic inventories. Dynamic inventories can populate themselves dynamically from an orchestration provider. Dynamic inventory plugins are written for most cloud providers as well as on-prem systems like Openstack and OpenShift.
Inventory Structure An Ansible inventory file follows an INI format or YAML format. The inventory file is simply a list of servers that you want to manage. The INI format uses simple key-value pairs to define host entries and groups while YAML format uses a more structured approach with indentation.
In an INI-based file:
1[webservers]
2host1.example.com
3host2.example.com
4
5[dbservers]
6db1.example.com
7db2.example.com
In a YAML-based file:
1all:
2 children:
3 webservers:
4 hosts:
5 host1.example.com:
6
7 dbservers:
8 hosts:
9 db1.example.com:
Each approach has its own advantages based on complexity and readability requirements. Choose a format that aligns with your team’s preferences and your infrastructure’s intricacy. In practice, when we want to structure small number of hosts, INI format is usually sufficient, but for large corporations, they might want to subdivide the hosts into department, groups, teams, etc. which is where YAML format provides lot more flexibility.
Ansible commands and playbooks can be run against an entire inventory (on all servers), one or more groups (for example, webservers or dbservers) or even single server. We can target the servers using group name in the command-line parameters. Ansible being an open source software has lots of modules to automate different tasks. As long as Ansible control node can communicate with the managed nodes in the inventory, you can automate any tasks.
Setting Up Inventory
The default location for the inventory file is at /etc/ansible/hosts. However, you can specify a different location using the -i option when running commands with ansible or by defining ANSIBLE_HOSTS environment variable.
To create a basic inventory file in INI format:
1web1.server.com
2web2.server.com
3web3.server.com
Adding alias to servers using below syntax
1web1 web1.server.com
2web2 web2.server.com
3web3 web3.server.com
4db db.server.com
Adding additional inventory parameters. Note that when connecting with Windows system, we need to specify connection as winrm.
1# Web Servers
2web1 ansible_host=server1.company.com ansible_connection=ssh ansible_user=root ansible_ssh_pass=Password123!
3web2 ansible_host=server2.company.com ansible_connection=ssh ansible_user=root ansible_ssh_pass=Password123!
4web3 ansible_host=server3.company.com ansible_connection=ssh ansible_user=root ansible_ssh_pass=Password123!
5db1 ansible_host=server4.company.com ansible_connection=winrm ansible_user=administrator ansible_password=Dbp@ss123!
Grouping and Parent-child relationship
Grouping hosts using groups
1# Web Servers
2web1 ansible_host=server1.company.com ansible_connection=ssh ansible_user=root ansible_ssh_pass=Password123!
3web2 ansible_host=server2.company.com ansible_connection=ssh ansible_user=root ansible_ssh_pass=Password123!
4web3 ansible_host=server3.company.com ansible_connection=ssh ansible_user=root ansible_ssh_pass=Password123!
5
6# Database Servers
7db1 ansible_host=server4.company.com ansible_connection=winrm ansible_user=administrator ansible_password=Password123!
8
9
10[web_servers]
11web1
12web2
13web3
14
15[db_servers]
16db1
Create new group from groups. Syntax looks like:
1[parent_group:children]
2group1
3group2
1# Web Servers
2web1 ansible_host=server1.company.com ansible_connection=ssh ansible_user=root ansible_ssh_pass=Password123!
3web2 ansible_host=server2.company.com ansible_connection=ssh ansible_user=root ansible_ssh_pass=Password123!
4web3 ansible_host=server3.company.com ansible_connection=ssh ansible_user=root ansible_ssh_pass=Password123!
5
6# Database Servers
7db1 ansible_host=server4.company.com ansible_connection=winrm ansible_user=administrator ansible_password=Password123!
8
9
10[web_servers]
11web1
12web2
13web3
14
15[db_servers]
16db1
17
18[all_servers:children]
19web_servers
20db_servers
1# Web Servers
2web_node1 ansible_host=web01.xyz.com ansible_connection=winrm ansible_user=administrator ansible_password=Win$Pass
3web_node2 ansible_host=web02.xyz.com ansible_connection=winrm ansible_user=administrator ansible_password=Win$Pass
4web_node3 ansible_host=web03.xyz.com ansible_connection=winrm ansible_user=administrator ansible_password=Win$Pass
5
6# DB Servers
7sql_db1 ansible_host=sql01.xyz.com ansible_connection=ssh ansible_user=root ansible_ssh_pass=Lin$Pass
8sql_db2 ansible_host=sql02.xyz.com ansible_connection=ssh ansible_user=root ansible_ssh_pass=Lin$Pass
9
10[db_nodes]
11sql_db1
12sql_db2
13
14[web_nodes]
15web_node1
16web_node2
17web_node3
18
19[boston_nodes]
20sql_db1
21web_node1
22
23[dallas_nodes]
24sql_db2
25web_node2
26web_node3
27
28[us_nodes:children]
29boston_nodes
30dallas_nodes
1[web]
2host1.example.com ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/private.pem
3
4[db]
5db1.example.com ansible_user=centos ansible_ssh_private_key_file=~/.ssh/key.pem
Here we’ve defined two groups: ‘web’ and ‘db’, along with their respective hosts and additional connection options like SSH user and private key path.
If you prefer using YAML format for better organization and flexibility:
1all:
2 children:
3 web:
4 hosts:
5 host1.example.com:
6 ansible_user: ubuntu
7 ansible_ssh_private_key_file: ~/.ssh/private.pem
8
9 db:
10 hosts:
11 db1.example.com:
12 ansible_user: centos
13 ansible_ssh_private_key_file: ~/.ssh/key.pem
Once your inventory file is set up, you can proceed with testing its connectivity using the ping module to ensure proper communication between the control node and managed nodes:
For INI-based inventory:
1ansible all -i /path/to/inventory -m ping
For YAML-based inventory:
1ansible all -i /path/to/inventory.yaml -m ping
Grouping Hosts You can organize your hosts into arbitrary groups based on practical categorization such as role, environment(like production or staging), location or application. It provides an organized approach when you have multiple servers belonging to different environments/application/services etc., in which they belong to through groupings.
For example:
1[web]
2host1.example.com
3
4[db]
5db1.example.com
6
7[staging]
8host2.staging-domain-example.net
9
10[production]
11host3.prod-domain-example.net
12
13[databaseservers:dbservers] # Group Alias & Group Name separated by colon (:)
14db4.servers.net # Hostname belongs to more than one group.
If you have multiple servers such as databaseservers & also app serves where these servers are common across Groups then creating an alias dbservers could be beneficial as it helps reduce duplication of list maintaining in both other categories namely databaseservers & appserver (or) webserver etc.,
Aliases also comes handy when saying that there are specific dbservers perform some role so such scenarios best suit this option.
After grouping servers under specified heading/group name now we specify same grouped server operations together as specified below:
1ansible-playbook - i /etc/hosts all --list-hosts | grep "webservers"
2ansible-playbook - i /etc/hosts all --list-hosts | grep "databaseservers" # Reports dbs clustername if any created under dbs alias.


Comments