Ansible Inventory

An Ansible controller needs a list of hosts and groups of hosts upon which commands, modules, and tasks are performed on the managed nodes, this list is known as inventory. It may contain information such as -- Host IPs, DNS Name, SSH User and Pass, SSH Port service info (in case it is other than port 22). The most common formats are INI and YAML. An inventory file is also sometimes called a host file. We will be using INI format in this guide.

A general inventory file might look like:

[webservers]
www.example1.com
www.example2.com
[dbservers]
192.x.x.x
10.x.x.x

Using default inventory file

The default location for inventory is /etc/ansible/hosts. We can also create our own host file.

Let's have a look and add one line to our default inventory.

192.168.25.16 ansible_ssh_pass=password

Here the IP of the remote machine is 192.168.25.16 and the password we are passing through ssh_pass utility (make sure you have sshpass installed). Default username is root and the connection by default is SSH.

Now, ping this IP through Ansible using below command:

ansible 192.168.25.16 -m ping

the output looks like below image

ansible-introduction

Here we are getting a PING = PONG response which means our connection is successful. PONG represents the return value on success.

Now, make the remote machine 192.168.25.16 unavailable by commenting the IP and try running the same command again:

vi /etc/ansible/hosts
# ansible 192.168.25.16 -m ping
ansible 192.168.25.16 -m ping

ansible-introduction

Creating custom inventory file

Although Ansible uses a default inventory file, we can create one of our own and can be customized as per the requirement.

  • Disabling host key checking Firstly, make a change in ansible.cfg file which is located at /etc/ansible directory Uncomment the line host_key_checking = False. This is to disable SSH key host checking: ssh-disable-host-key-checking

  • Create inventory file In /etc/ansible/ directory, and create inventory.txt file, and add below details to it: vi inventory.txt

    webserver1 ansible_host=192.168.25.15 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
    

    ansible-inventory-file

  • Using custom inventory file To ping the webserver1, run the command below:

    $ansible webserver1 -m ping -i inventory.txt
    

    Note: If we do not pass -i flag, it will use the default host file instead of inventory.txt

Consider inventory.txt file has one more entry as -

webserver ansible_host=192.168.25.15 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
sqlserver ansible_host=192.168.25.16 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root

To ping the sqlserver, the command would be -

$ansible sqlserver -m ping -i inventory.txt

To ping all the machines in inventory1.txt file, use the command below:

ansible all -m ping -i inventory1.txt

Now, let's consider that inventory file has couple of similar entries for webservers and sqlservers as below:

webserver1 ansible_host=192.168.25.15 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
webserver2 ansible_host=192.168.25.14 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
webserver3 ansible_host=192.168.25.13 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
webserver4 ansible_host=192.168.25.12 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
webserver5 ansible_host=192.168.25.11 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
sqlserver1 ansible_host=192.168.25.16 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
sqlserver2 ansible_host=192.168.25.17 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
sqlserver3 ansible_host=192.168.25.18 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
sqlserver4 ansible_host=192.168.25.19 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
sqlserver5 ansible_host=192.168.25.20 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root

To ping all the hostnames starting with 'webserver', we can also use wild card (*) using below command:

$ansible webserver* -m ping -i inventory2.txt

This will ping all the webservers.

If any of the servers is not reachable, you will see error as below - ansible-inventory-file

Organizing Servers Into Groups and Subgroups in Inventory file

Within the inventory file, you can organize your servers into different groups and subgroups. This will help in managing multiple staging environments with Ansible.

The following inventory file contains a set of three groups:

webservers, databaseservers, nfsservers

vi ansible inventory_all.txt

webserver1 ansible_host=192.168.25.15 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
webserver2 ansible_host=192.168.25.17 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
webserver3 ansible_host=192.168.25.18 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root

sqlserver1 ansible_host=192.168.25.19 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
sqlserver2 ansible_host=192.168.25.20 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
sqlserver3 ansible_host=192.168.25.21 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root

nfsserver1 ansible_host=192.168.25.19 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
nfsserver2 ansible_host=192.168.25.20 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
nfsserver3 ansible_host=192.168.25.21 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root

[webservers]
webserver1
webserver2
webserver3

[dbservers]
dbserver1
dbserver2
dbserver3

[nfsservers]
nfsserver1
nfsserver2
nfsserver3

In the above file, we can also label servers as -

[nfsservers]
nfsserver[1:3]

And, it is also possible to aggregate multiple groups as children under a "parent" group. The "parent" is then called a metagroup.

vi group_inventory.txt

webserver1 ansible_host=192.168.25.15 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
webserver2 ansible_host=192.168.25.17 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
webserver3 ansible_host=192.168.25.18 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root

sqlserver1 ansible_host=192.168.25.19 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
sqlserver2 ansible_host=192.168.25.20 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
sqlserver3 ansible_host=192.168.25.21 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root

nfsserver1 ansible_host=192.168.25.19 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
nfsserver2 ansible_host=192.168.25.20 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
nfsserver3 ansible_host=192.168.25.21 ansible_ssh_pass=password ansible_connection=ssh ansible_port=22 ansible_user=root
[webservers]
webserver1
webserver2
webserver3

[dbservers]
dbserver1
dbserver2
dbserver3

[nfsservers]
nfsserver[1:3]

[production:children]
webservers
dbservers

When we run below command it will ping all the webservers and dbserver that are present in group_inventory.txt file.

$ansible production -m ping -i group_inventor.txt