Introduction to Ansible Inventory Management

Ansible is a simple open-source agentless IT automation tool used for configuration management and automatic deployment of applications. With ansible, a simple YAML code is written once for the installation and deployed multiple times.

Ansible uses an inventory to work against multiple managed nodes or “hosts” in your infrastructure at the same time. After you’ve defined your inventory, you can use patterns to select which hosts or groups you want Ansible to run against.

A good introduction about Ansible was done in our previous article on Introduction to Ansible Automation on Linux – Understanding Ansible

In this article, our focus will be on “Ansible Inventory Management”.

Ansible Inventory Management

The Ansible inventory file is a list of hosts or a group of hosts on which commands, modules, and tasks in playbook operate. The default location for the host inventory file is /etc/ansible/hosts. The ansible commands use a different host inventory file when they are used with the --inventory PATHNAME option, simplified as -i PATHNAME.

By passing multiple inventory parameters from the command line or configuring ANSIBLE_INVENTORY, you can target multiple inventory sources (directories, dynamic inventory scripts, or files supported by inventory plugins) at the same time. You can also pull inventory from dynamic or cloud sources, as well as different formats such as YAML, ini, and so on.

Modules are the programs that perform the actual work of the tasks of a play. Core modules come bundled with Ansible. There are more than 300 core modules to choose from.

The goal of a play is to map a group of hosts to well-defined roles. These are called tasks. A task is a call to an ansible module.

Individual hosts or user-defined groups of hosts can be listed in the inventory file.

Ansible playbooks are written using the YAML language. YAML files have a .yml extension. YAML files optionally begin with a three dash

(—). Immediately after the three dashes, the line starts with a single dash (-). Next, we define hosts or group of hosts. You then define whether you will be a root user or not by using the keyword become. Then immediately after you define the tasks and finally define your modules.

How to define Inventory in Ansible

Before we embark on defining an Inventory, we must ensure the following requirements are met.

  1. One Ansible control node.
  2. Two or more Ansible hosts.

Step 1 : Install Ansible in your system

In the previous article, we touched on Ansible installation.

Installation of Ansible from OS package manager

The quickest and easiest method is installing Ansible using package manager:

### Ubuntu / Debian ###
sudo apt update
sudo apt install ansible

### CentOS 8 / Rocky Linux 8 / AlmaLinux 8 ###
sudo yum install epel-release
sudo yum install ansible

### Arch / Manjaro ###
sudo pacman -S ansible

### macOS ###
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install ansible
Installation of Ansible using Pip/Pip3

Alternative method is the installation of Ansible using Pip Python package manager:

### Ubuntu / Debian ###
sudo apt update
sudo apt install python3 python3-pip
sudo pip3 install ansible

### CentOS 8 / Rocky Linux 8 / AlmaLinux 8 ###
sudo yum install python3  python3-pip
sudo pip3 install ansible

Confirm Ansible version installed in your system:

$ ansible --version
ansible [core 2.11.5]
  config file = None
  configured module search path = ['/home/rocky/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.6/site-packages/ansible
  ansible collection location = /home/rocky/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.6.8 (default, Sep 21 2021, 18:40:00) [GCC 8.4.1 20200928 (Red Hat 8.4.1-1)]
  jinja version = 2.10.1
  libyaml = True

Step 2 : Set up your Inventory file

Ansible creates an inventory file during installation, which is normally located at /etc/ansible/hosts. During a playbook or command execution, Ansible uses this as the default location if a custom inventory file is not specified with the -i option.

To edit the contents of your default Ansible location, use the text editor of your choice and edit the /etc/ansible/hosts file.

sudo vi /etc/ansible/hosts

Command output :

# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
#   - Comments begin with the '#' character
#   - Blank lines are ignored
#   - Groups of hosts are delimited by [header] elements
#   - You can enter hostnames or ip addresses
#   - A hostname/ip can be a member of multiple groups

# Ex 1: Ungrouped hosts, specify before any group headers.

## green.example.com
## blue.example.com
## 192.168.100.1
## 192.168.100.10

# Ex 2: A collection of hosts belonging to the 'webservers' group

## [webservers]
## alpha.example.org
## beta.example.org
## 192.168.1.100
.
.
.
.
## [dbservers]
##
## db01.intranet.mydomain.net
## db02.intranet.mydomain.net
## 10.25.1.56
## 10.25.1.57

# Here's another example of host ranges, this time there are no
# leading 0s:

## db-[99:101]-node.example.com

[Servers]
192.168.201.2
192.168.201.3

[Servers:vars]
ansible_user=Jil
ansible_password='***********@1987'

Towards the end of the configuration file, I have created a group called [Servers] and listed their IP addresses. These are my two servers for the purposes of this article. In [Servers:vars] i have defined my servers variables, which include my server user and password.

After making your changes save and exit your editor.

We will do one more thing. We will now allow host_key_checking in the ansible.cfg file.

using your text editor :

sudo vi /etc/ansible/ansible.cfg

Scroll down till you get to this line of the script

# uncomment this to disable SSH key host checking
# host_key_checking = False

Uncomment the line to disable SSH key host checking.

host_key_checking = False

Save and exit your editor.

Step 3: Testing connection from control node

We will now test if our Ansible control node is able to connect to our two hosts. This will be achieved by pinging our hosts:

sudo ansible Servers -m ping

The output:

[cloudspinx@rocky-linux ~]$ ansible Servers -m ping
[DEPRECATION WARNING]: Distribution fedora 34 on host 192.168.201.3 should use 
/usr/bin/python3, but is using /usr/bin/python for backward compatibility with 
prior Ansible releases. A future Ansible release will default to using the 
discovered platform python for this host. See https://docs.ansible.com/ansible/
2.9/reference_appendices/interpreter_discovery.html for more information. This 
feature will be removed in version 2.12. Deprecation warnings can be disabled 
by setting deprecation_warnings=False in ansible.cfg.
192.168.201.3 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
192.168.201.2 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"

Congratulations, you have successfully pinged your hosts from your Ansible control node.

Step 4 : Running Ad-hoc commands

Once the connection is successful, it’s time to test an ad-hoc command. In this article, I will check the OS release running on my two Servers and the disk usage.

Check my Servers OS release

This can be done by executing this command:

ansible Servers -a "cat /etc/os-release"

The output of the command.

[cloudspinx@rocky-linux ~]$ ansible Servers -a "cat /etc/os-release"
192.168.201.2 | CHANGED | rc=0 >>
NAME="Rocky Linux"
VERSION="8.4 (Green Obsidian)"
ID="rocky"
ID_LIKE="rhel centos fedora"
VERSION_ID="8.4"
PLATFORM_ID="platform:el8"
PRETTY_NAME="Rocky Linux 8.4 (Green Obsidian)"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:rocky:rocky:8.4:GA"
HOME_URL="https://rockylinux.org/"
BUG_REPORT_URL="https://bugs.rockylinux.org/"
ROCKY_SUPPORT_PRODUCT="Rocky Linux"
ROCKY_SUPPORT_PRODUCT_VERSION="8"
[DEPRECATION WARNING]: Distribution fedora 34 on host 192.168.201.3 should use 
/usr/bin/python3, but is using /usr/bin/python for backward compatibility with 
prior Ansible releases. A future Ansible release will default to using the 
discovered platform python for this host. See https://docs.ansible.com/ansible/
2.9/reference_appendices/interpreter_discovery.html for more information. This 
feature will be removed in version 2.12. Deprecation warnings can be disabled 
by setting deprecation_warnings=False in ansible.cfg.
192.168.201.3 | CHANGED | rc=0 >>
NAME=Fedora
VERSION="34 (Server Edition)"
ID=fedora
VERSION_ID=34
VERSION_CODENAME=""
PLATFORM_ID="platform:f34"
PRETTY_NAME="Fedora 34 (Server Edition)"
ANSI_COLOR="0;38;2;60;110;180"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:34"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f34/system-administrators-guide/"
SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=34
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=34
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
VARIANT="Server Edition"
VARIANT_ID=server
[Jil@rocky-linux ~]$ 
Check my Servers disk usage

To check disk usage, you would run this command:

ansible Servers -a "df -h" -u Jil

Command output :

[cloudspinx@rocky-linux ~]$ ansible Servers -a "df -h" -u clouflare
[DEPRECATION WARNING]: Distribution fedora 34 on host 192.168.201.3 should use 
/usr/bin/python3, but is using /usr/bin/python for backward compatibility with 
prior Ansible releases. A future Ansible release will default to using the 
discovered platform python for this host. See https://docs.ansible.com/ansible/
2.9/reference_appendices/interpreter_discovery.html for more information. This 
feature will be removed in version 2.12. Deprecation warnings can be disabled 
by setting deprecation_warnings=False in ansible.cfg.
192.168.201.3 | CHANGED | rc=0 >>
Filesystem                      Size  Used Avail Use% Mounted on
devtmpfs                        1.9G     0  1.9G   0% /dev
tmpfs                           2.0G     0  2.0G   0% /dev/shm
tmpfs                           783M  1.1M  782M   1% /run
/dev/mapper/fedora_fedora-root   15G  1.8G   14G  12% /
tmpfs                           2.0G   88K  2.0G   1% /tmp
/dev/vda1                      1014M  234M  781M  24% /boot
tmpfs                           392M     0  392M   0% /run/user/1000
192.168.201.2 | CHANGED | rc=0 >>
Filesystem           Size  Used Avail Use% Mounted on
devtmpfs             3.8G     0  3.8G   0% /dev
tmpfs                3.8G     0  3.8G   0% /dev/shm
tmpfs                3.8G  9.2M  3.8G   1% /run
tmpfs                3.8G     0  3.8G   0% /sys/fs/cgroup
/dev/mapper/rl-root   48G  5.0G   43G  11% /
/dev/mapper/rl-home   24G  213M   24G   1% /home
/dev/vda1           1014M  324M  691M  32% /boot
tmpfs                777M  1.2M  776M   1% /run/user/42
tmpfs                777M  4.0K  777M   1% /run/user/1000
[Jil@rocky-linux ~]$ 

Wow, that is cool, isn’t it? You have successfully run an ad-hoc command. There is no limit to what you can achieve with ad-hoc commands, from installing packages to individual nodes, upgrading systems, shutting down some services, and so on.

Running playbooks in Ansible

Lets create a playbook that will check if vi text editor is available on our Servers group created above.

Step 1: Create a playbook file.

To create a playbook file:

sudo ansible-playbook ilovevim.yml

Paste this code :

---
- name: ilovevim
  hosts: Servers
  tasks:
   - name: ensure vim is installed
     yum:
      name: vi
      state: latest

From the sample output, – name: ilovevim defines our play, hosts: Servers defines our two servers hosts created above, – name: ensure vi is here defines our task, yum: is our module.

Save and exit and your text editor.

Step 2: Running the playbook file.

Once you have created your playbook and defined all the parameters, run your playbook.

sudo ansible-playbook ilovevim.yml 

Command output:

[cloudspinx@rocky-linux ansible]$ sudo ansible-playbook ilovevim.yml 

PLAY [ilovevim] ****************************************************************

TASK [Gathering Facts] *********************************************************
[DEPRECATION WARNING]: Distribution fedora 34 on host 192.168.201.3 should use 
/usr/bin/python3, but is using /usr/bin/python for backward compatibility with 
prior Ansible releases. A future Ansible release will default to using the 
discovered platform python for this host. See https://docs.ansible.com/ansible/
2.9/reference_appendices/interpreter_discovery.html for more information. This 
feature will be removed in version 2.12. Deprecation warnings can be disabled 
by setting deprecation_warnings=False in ansible.cfg.
ok: [192.168.201.3]
ok: [192.168.201.2]

TASK [ensure vi is here] *******************************************************
ok: [192.168.201.2]
ok: [192.168.201.3]

PLAY RECAP *********************************************************************
192.168.201.2              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.201.3              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

The output ok=2 changed=0 for our two servers indicates that no changes were made. Ansible never make changes for something that is already there. This, therefore, means that our task to check if vi is there/installed in our servers is already present i.e vi is present in our two hosts, and it’s already in the current state. Ansible will only make a change if the change is not there.

What if we wanted to remove vim our hosts?

Go to your ilovevim.yml playbook and change the state to removed.

---
- name: Ensure vim is removed on the system
  hosts: Servers
  tasks:
   - name: ensure vim is removed
     package:
      name: vim
      state: absent

Save and exit your editor the run the playbook:

[cloudspinx@rocky-linux ansible]$ ansible-playbook ilovevim.yml 

PLAY [ilovevim] **************************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************
[DEPRECATION WARNING]: Distribution fedora 34 on host 192.168.201.3 should use /usr/bin/python3, but is using /usr/bin/python for backward 
compatibility with prior Ansible releases. A future Ansible release will default to using the discovered platform python for this host. See 
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information. This feature will be removed in version 
2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
ok: [192.168.201.3]
ok: [192.168.201.2]

TASK [remove vim] ************************************************************************************************************************************
ok: [192.168.201.2]
ok: [192.168.201.3]

TASK [ensure vi is here] *****************************************************************************************************************************
ok: [192.168.201.2]
ok: [192.168.201.3]

PLAY RECAP *******************************************************************************************************************************************
192.168.201.2              : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.201.3              : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Congratulations on running your playbook.

Conclusion

In this guide, you have successfully defined an Ansible Inventory, connected to nodes, and checked on a few ad-hoc examples on how to use ansible. We also briefly looked at playbook. This was a brief guide and we do hope you have followed along. With Ansible you can automate Infrastructure, Applications, networks, Containers, Security, and Cloud. This is a tool that every SysAdmin should have at his/her disposal to help him achieve much more in a very short time. Thank you.

See more resources:

Your IT Journey Starts Here!

Ready to level up your IT skills? Our new eLearning platform is coming soon to help you master the latest technologies.

Be the first to know when we launch! Join our waitlist now.

Join our Linux and open source community. Subscribe to our newsletter for tips, tricks, and collaboration opportunities!

Recent Post

Leave a Comment

Your email address will not be published. Required fields are marked *

Related Post

Android Studio, which is based on IntelliJ IDEA, is the official Integrated Development Environment for developing Android apps. On top […]

In this guide, we will walk through how to install Webmin on AlmaLinux 9 or Oracle Linux 9. Webmin is […]

Grub, an acronym of Grand Unified Bootloader is the most preferred boot loader on Linux systems although there are others […]

Let's Connect

Unleash the full potential of your business with CloudSpinx. Our expert solutions specialists are standing by to answer your questions and tailor a plan that perfectly aligns with your unique needs.
You will get a response from our solutions specialist within 12 hours
We understand emergencies can be stressful. For immediate assistance, chat with us now

Contact CloudSpinx today!

Download CloudSpinx Profile

Discover the full spectrum of our expertise and services by downloading our detailed Company Profile. Simply enter your first name, last name, and email address.