How to Setup Ansible Inventory and How it Works (Tutorial)

How to Setup Ansible Inventory and How it Works (Tutorial). Well Ansible is a modern configuration management tool that is used for setting up and maintaining remote servers. Its minimalist design enables users to get up and run instantly. It also uses inventory files to keep track of the hosts that are part of your infrastructure and different ways that can be used to reach them for running commands and playbooks. This inventory can be set up in several contrasting ways based on the environment and project needs. In this guide we will introduce Ansible inventory with it’s main advantages then move onto inventory setup phase on Ubuntu 20.04

Let’s proceed with How to Setup Ansible Inventory and How it Works.

What Is Ansible

Firstly Ansible is an open source IT automation engine that mitigates hard work from the work life. It boosts scalability, consistency and reliability of your IT environment.

You can use this tool for automation in three different ways:

1. Provisioning – It helps you in setting up the servers required in the infrastructure.

2. Configuration Management 

  • Changing the configuration of an application, device, or OS
  • Starts and stops services.
  • Install or update applications.
  • Implement a security policy.
  • Perform multiple configuration tasks.

3. Application Deployment – It makes DevOps effortless by automating the deployment of internally developed applications to your production systems. 

Additionally Ansible is best known for automating IT environments hosted on traditional bare metal servers, virtualization platforms, or in the cloud. It can also be used for automating the configuration of a broader range of systems and devices, including databases, storage devices, networks, firewalls, and a lot more.

Moreover, the highly advantageous point about Ansible is that you can accomplish particular tasks even if you are not proficient in commands. All you need is to specify the state required for the system, and the rest will be taken care of by this tool.

Ansible Features

The features you can enjoy using Ansible are:

  • Enables you to instantly deploy multiple apps.

What Is Ansible Inventory File

Firstly Ansible tends to work against multiple systems in your infrastructure. This procedure is performed by making the selection from the portion of systems stored in the Ansible Inventory File saved automatically in a particular location. Then Ansible also enables you to specify a different inventory file using a particular option on the command line.

The inventory is not only configurable but also allows you to use several different inventory files at the same time.

In a nutshell, Ansible Inventory Files are the hosts and group of hosts upon which commands, modules, and tasks in a playbook tend to operate. Moreover, depending on your Ansible environments and plugins, the file is deployed in several different formats, including IMI and YAML.

Ansible Inventory Files categories

Inventory Files are divided into different parts that are as given below:

  • Hosts and Groups – Ansible Inventory includes hosts and group names that are used in classifying systems and deciding what systems are being controlled at a particular time and for a particular purpose. Here, you can put systems in more than one group. However, it is essential to remember that variables can come from all of the groups they are a member of.
  • Host Variables – As discussed above, you can effortlessly assign variables to hosts to later used them in playbooks.
  • Group Variables – You can also apply variables to the entire group at once.
  • Groups Of Groups and Groups VariablesAnsible Inventory allows you to make groups of groups and Group variables.
  • Default Groups – Ansible Inventory File consists of two default groups, namely all and ungrouped. While ‘all’ contains all the hosts, ‘ungrouped’ contains hosts that do not have another group apart from ‘all.’

How Does Ansible Inventory Works?

The default path of the Ansible inventory is /etc/ansible/hosts. However, you can also create an inventory file at separate location. Let’s take a look at a sample inventory file. The inventory file is an INI like format its simply a number of servers listed one after the others.

You can enter the name of the group within a pair of square brackets and define the list of servers part of that group in the lines below. You can have multiple such groups defined in a single inventory file. This is so you can target a group of servers for any Ansible playbook to configure all of them at once. Finally, you can also have a group of groups. In order to define a group of groups follows the same pattern as group creation except in this case you must add a colon followed by the keyword children to the parent group’s name. In this case, I would like to create a group named all_servers that contains all servers in the group’s mail, db, and web. And so I defined the group name all_servers within the square brackets followed by a colon in the keyword children.

Let’s take a deeper look at an inventory file. For example, I have a list of servers named from 1 to 4 as shown in the following screen:

define hosts in inventory file

However, I would like to refer to these servers in Ansible using an alias such as web server, database server and mail server. I could deal this by adding an alias for each server at the beginning of the line and assigning the address of the server to ansible_host parameter.With  ansible_host as an inventory parameter used to specify the FQDN or IP address of a server. There are other inventory parameters too. Some of the other key ansible parameters are ansible_connection, ansible_port, ansible_user, and ansible_ssh_pass.

Ansible Parameters

A brief explanation of each parameter is shown below:

  • ansible_connection defines how Ansible connects to the Target server. This is how we define a Target host we wish to connect to is a Linux or a Windows host. You could also set it to localhost to indicate that you would like to work with localhost and not connect to any remote host. If you don’t have multiple remote servers to play around with you can simply start with localhost into an inventory file.
  • ansible_port defines which port to connect to. By default, it is set to 22 for SSH. But if you need to change that for some reason you can set it differently using the ansible_port parameter.
  • ansible_user defines the user to make remote connections. If you need to change that define it as shown here.
  • ansible_ssh_pass defines the SSH password for Linux.

In this post, we will show you how to create Ansible Inventory with some examples.

How to Setup Ansible Inventory and How it Works

Prerequisites

  • Two servers running Ubuntu 20.04 for Ansible Managed Nodes with static IP addresses 192.168.0.100 and 192.168.0.101.
  • A root user or a user with sudo privileges on each node.

Install Ansible on Control Node

By default, the latest version of Ansible is not included in the Ubuntu 20.04 default repository. So you will need to add the Ansible repository to APT.

Firstly install all required dependencies using the following command:

				
					apt install curl gnupg2 software-properties-common -y
				
			

Once all the required dependencies are installed, add the Ansible repository to APT using the following command:

				
					add-apt-repository --yes --update ppa:ansible/ansible
				
			

Then update the repository and install the Ansible with the following command:

				
					apt update
apt install ansible
				
			

Once the Ansible is installed, verify the Ansible version using the following command:

				
					ansible --version
				
			

You should see the following output:

				
					ansible [core 2.12.7]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.8.10 (default, Mar 15 2022, 12:22:08) [GCC 9.4.0]
  jinja version = 2.10.1
  libyaml = True
				
			

Setup an SSH Password-Less Authentication

Following that you will need to setup an SSH password-less authentication between the Ansible control and managed node. On the Ansible control node machine, generate an SSH key with the following command:

				
					ssh-keygen -t rsa
				
			

You should see the following output:

				
					Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory 'https://net.cloudinfrastructureservices.co.uk/root/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:pwV2R+of52iRcg9eiUepkhvVmwWmn4B2f5PZ3Rq9iDM root@linux
The key's randomart image is:
+---[RSA 3072]----+
|            . o  |
|           + + o |
|        o = * + .|
|       . = = O B*|
|        S O O %+*|
|         + O.@.+o|
|        . .E=.+. |
|           .o    |
|                 |
+----[SHA256]-----+
				
			

Now copy the generated SSH key to the Ansible managed nodes. Let’s copy an SSH public key to the first Ansible managed node:

				
					ssh-copy-id root@192.168.0.100
				
			

You should see the following output:

				
					/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "https://net.cloudinfrastructureservices.co.uk/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.0.100 (192.168.0.100)' can't be established.
ECDSA key fingerprint is SHA256:3LOmcVmMuWeHCcJ32xQI7ApmVGSUzktFH/XJRc/OHCs.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.0.100's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@192.168.0.100'"
and check to make sure that only the key(s) you wanted were added.

				
			

After that please copy an SSH key to the second Ansible managed node:

				
					ssh-copy-id root@192.168.0.101
				
			

You should see the following output:

				
					/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "https://net.cloudinfrastructureservices.co.uk/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.0.101 (192.168.0.101)' can't be established.
ECDSA key fingerprint is SHA256:3LOmcVmMuWeHCcJ32xQI7ApmVGSUzktFH/XJRc/OHCs.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.0.101's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@192.168.0.101'"
and check to make sure that only the key(s) you wanted were added.
				
			

Create an Ansible Inventory File

Afterwards  you will need to create an Ansible inventory file to define your managed nodes. First, create a directory to hold the Ansible inventory file:

				
					mkdir project
				
			

In  here create an inventory file with the following command:

				
					cd project
nano inventory.txt
				
			

Add the following lines:

				
					[webserver]
web ansible_host=192.168.0.100 ansible_user=root


[database]
db ansible_host=192.168.0.101 ansible_user=root

				
			

Save and close the file when you are finished.

A brief explanation of the Ansible inventory file is shown below:

  • web and db is the name of the Ansible managed node.
  • 192.168.0.100 and 192.168.0.101 is the IP address of each node.
  • ansible_user is the user name of each node.

You can now list all your nodes added in the inventory file using the following command:

				
					ansible-inventory --list -i inventory.txt 
				
			

You will get the following output:

				
					{
    "_meta": {
        "hostvars": {
            "db": {
                "ansible_host": "192.168.0.101",
                "ansible_user": "root"
            },
            "web": {
                "ansible_host": "192.168.0.100",
                "ansible_user": "root"
            }
        }
    },
    "all": {
        "children": [
            "database",
            "ungrouped",
            "webserver"
        ]
    },
    "database": {
        "hosts": [
            "db"
        ]
    },
    "webserver": {
        "hosts": [
            "web"
        ]
    }
}
				
			

How to Use Ansible Inventory

In this section, we will show you how to use the Ansible inventory file and run some Adhoc commands to manage remote nodes.

In order to verify the connectivity of the web node, run the following command:

				
					ansible web -m ping -i inventory.txt
				
			

You will get the following output:

				
					web | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
				
			

To verify the connectivity of the db node, run the following command:

				
					ansible db -m ping -i inventory.txt
				
			

You will get the following output:

				
					db | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
				
			

And to verify the connectivity of all nodes, run the following command:

				
					ansible all -m ping -i inventory.txt
				
			

You should see the following output:

				
					db | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
web | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}

				
			

If you want to see the disk space on all nodes, run the following command:

				
					ansible all -a "df -h" -i inventory.txt
				
			

You should see the following output:

				
					db | CHANGED | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
udev            979M     0  979M   0% /dev
tmpfs           199M  720K  198M   1% /run
/dev/sda1        50G  3.4G   44G   8% /
tmpfs           992M  124K  992M   1% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           992M     0  992M   0% /sys/fs/cgroup
tmpfs           199M     0  199M   0% /run/user/0
overlay          50G  3.4G   44G   8% /var/lib/docker/overlay2/e689df5289cca2c598cd848eb9089aed9439e09cbd33692d938cf6ef95e488e3/merged
web | CHANGED | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
udev            979M     0  979M   0% /dev
tmpfs           199M  720K  198M   1% /run
/dev/sda1        50G  3.4G   44G   8% /
tmpfs           992M  124K  992M   1% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           992M     0  992M   0% /sys/fs/cgroup
tmpfs           199M     0  199M   0% /run/user/0
overlay          50G  3.4G   44G   8% /var/lib/docker/overlay2/e689df5289cca2c598cd848eb9089aed9439e09cbd33692d938cf6ef95e488e3/merged

				
			

To check the uptime of the web node, run the following command:

				
					ansible webserver -a "uptime" -i inventory.txt
				
			

You should see the following output:

				
					web | CHANGED | rc=0 >>
 08:46:27 up  3:34,  3 users,  load average: 0.11, 0.14, 0.09

				
			

Check the Apache server status on the web node, run the following command:

				
					ansible web -a "systemctl status apache2" -i inventory.txt
				
			

You should see the following output:

				
					web | CHANGED | rc=0 >>
● apache2.service - The Apache HTTP Server
     Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2022-07-28 07:35:03 UTC; 1h 11min ago
       Docs: https://httpd.apache.org/docs/2.4/
    Process: 16664 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS)
   Main PID: 16682 (apache2)
      Tasks: 55 (limit: 2347)
     Memory: 6.7M
     CGroup: /system.slice/apache2.service
             ├─16682 /usr/sbin/apache2 -k start
             ├─16683 /usr/sbin/apache2 -k start
             └─16684 /usr/sbin/apache2 -k start

Jul 28 07:35:03 linux systemd[1]: Starting The Apache HTTP Server...
Jul 28 07:35:03 linux apachectl[16675]: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 208.117.87.81. Set the 'ServerName' directive globally to suppress this message
Jul 28 07:35:03 linux systemd[1]: Started The Apache HTTP Server.

				
			

To check the free memory on the db node, run the following command:

				
					ansible db -a "free -m" -i inventory.txt
				
			

You should see the following output:

				
					db | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:           1983        1450         102           2         430         372
Swap:             0           0           0

				
			

Thank you for your time in reading How to Setup Ansible Inventory and How it Works.

How to Setup Ansible Inventory and How it Works Conclusion

In this post, we explained how to setup an Ansible Inventory on Ubuntu 20.04. We also demonstrated some real life examples to manage and monitor remote nodes using Ansible Adhoc commands. The inventory is not only configurable but also allows you to use several different inventory files at the same time.

Please take a look at our Ansible content as well in here.

Avatar for Hitesh Jethva
Hitesh Jethva

I am a fan of open source technology and have more than 10 years of experience working with Linux and Open Source technologies. I am one of the Linux technical writers for Cloud Infrastructure Services.

0 0 votes
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x