Home Ansible Ansible Inventory And Configuration Files

Ansible Inventory And Configuration Files

By Karthick
Published: Updated: 11.4K views

A few days ago, we have discussed how to set up a three-node Ansible lab using Vagrant in Linux. In this article, we are going to learn Ansible fundamental concepts such as Ansible inventory and configuration files in detail.

Basic Structure Of Ansible

When you start working with ansible, there are two important files you should understand about. One is Ansible inventory file and the second is the Ansible configuration file.

The configuration file contains all the configurations that ansible will use during the run time. When you install ansible using the OS package manager, then you can see there is a default configuration file named "ansible.cfg" created in /etc/ansible directory.

The inventory file contains the IP address or DNS information about the list of managed hosts we want to work with. Ansible will read the hostnames from the inventory file and the tasks/plays will be executed on that nodes. Inventory files can be created in ini, yaml, and json formats.

Below is the structure of my project. I have an ansible.cfg configuration file, a hosts file, and a playbook which is written in yaml format.

When I trigger the playbook, ansible will read the configuration from ansible.cfg file and the host details from the hosts file to run the plays.

vagrant@controller:~/ansible_project$ tree .
.
├── ansible.cfg
├── hosts
└── playbook.yml

0 directories, 3 files

Let’s talk in detail about these two files and we will finally run some adhoc commands.

Ansible Configuration File

Ansible uses the configuration file to load the parameters that are required to run the ansible task. If you have installed ansible using the package manager, you will have an ansible.cfg file in /etc/ansible directory.

Below is the sample of the ansible.cfg file.

Ansible Configuration File
Ansible Configuration File

Ansible will look for the configuration file in the following order.

  • ANSIBLE_CONFIG - environment variable
  • ansible.cfg - Current directory from where you are running the command
  • .ansible.cfg - Users home directory
  • /etc/ansible/ansible.cfg - In /etc/ansible directory

Run ansible --version command to see which configuration file ansible is picking.

$ ansible --version
ansible [core 2.12.3]
  config file = /home/vagrant/ansible_project/ansible.cfg
  configured module search path = ['/home/vagrant/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.8/dist-packages/ansible
  ansible collection location = /home/vagrant/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.8.10 (default, Nov 26 2021, 20:14:08) [GCC 9.3.0]
  jinja version = 2.10.1
  libyaml = True

I have created a custom project directory and created a ansible.cfg file. My config file contains only two properties, inventory location, and disabled host key checking.

[defaults]
inventory = /home/karthick/ansible_project/hosts
host_key_checking = False

There are tons of other properties but at the moment you can start using them by adding "inventory" property alone.

Ansible Inventory File

In the inventory file, we will give the IP address or DNS of server names, network devices, cloud services, or anything that ansible can work with.

Inventories can be written in ini, json, and yaml format and you also have scripts to convert one inventory format to other formats.

By default, you can find an inventory file(hosts) in /etc/ansible directory if you have installed ansible using OS package manager. It is always recommended to create a separate project directory and create an inventory and config file.

The below table represents how my ansible lab is set up. I am going to create the inventory file for this lab setup and will run the ping module to demonstrate how things work in the inventory file.

NODE TYPENODE NAMEIP ADDRESSOS FLAVOR
Control Nodecontroller.anslab.com192.168.10.3ubuntu/focal64
Managed Nodemanaged1.anslab.com192.168.10.4ubuntu/focal64
Managed Nodemanaged2.anslab.com192.168.10.5ubuntu/focal64
Three Node Ansible Lab Setup

Inventory File Without Explicit Grouping

Inventory file has a concept called grouping where you will be grouping your resources and run tasks against that group. It will be in the following structure.

[group-name]
Resource1
Resource2
....
Resource N

You can create the inventory file without using groups. In this case, Ansible will use two default groups "all" and "ungrouped".

  • ALL GROUP - All resources that are available in the inventory file by default will be assigned to all group.
  • UNGROUPED - Resources that are not part of any user-defined groups will be automatically assigned to the ungrouped group.

I have created an inventory file without any groups. Now, these two nodes will come under all group as well as the ungrouped group.

$ cat hosts
managed1.anslab.com
managed2.anslab.com

You can run the following ansible command to check the list of hosts under all and ungrouped group.

$ ansible all --list-hosts
  hosts (2):
    managed1.anslab.com
    managed2.anslab.com
$ ansible ungrouped --list-hosts
  hosts (2):
    managed1.anslab.com
    managed2.anslab.com

Inventory File With Grouping

As foretold, grouping is a great way to organize your resources so it will be easy for you to run the task against the specific group. I have two managed nodes and they run Ubuntu 20.04LTS.

Let’s say I want to group my inventory file based on the OS type then the inventory file will look like below. Here ubuntu is the group name.

[ubuntu]
managed1.anslab.com
managed2.anslab.com

Tasks can be run against this group.

$ ansible ubuntu -m ping -o
managed1.anslab.com | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": false,"ping": "pong"}
managed2.anslab.com | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": false,"ping": "pong"}

If I check for the "ungrouped" group now, no host will be there.

$ ansible ungrouped --list-hosts
[WARNING]: No hosts matched, nothing to do
hosts (0):

You can create as many groups you want in the inventory file and use the same resource names.

[ubuntu]
managed1.anslab.com
managed2.anslab.com

[dev]
managed1.anslab.com

[test]
managed2.anslab.com
$ ansible ubuntu -m ping -o
$ ansible dev -m ping -o
$ ansible test -m ping -o

Inventory File With Ranges

When you have a common naming pattern for your resources, you can use ranges. Take a look at the below example where Instead of repeating the DNS I have used the range to shorten it.

[ubuntu]
managed[1:2].anslab.com

Inventory File With Child Groups

You can create a group and use other group names under it. Take a look at the below example, I have the ubuntu group which has my server names. I have created another group named server which contains the ubuntu group.

It is important you add :children to the group name otherwise the server group will treat "ubuntu" as the server name instead of the group name.

[ubuntu]
managed[1:2].anslab.com

[server:children]
ubuntu

Inventory File With Host Vars & Group Vars

Inventory file supports host & group variables. Host variables are nothing but variables and their values passed to the host in the inventory file. In the below configuration I am telling ansible to use ostechnix as my user and instead of using standard ssh port, use port 2222.

[ubuntu]
managed1.anslab.com ansible_user=ostechnix ansible_port=2222
managed2.anslab.com ansible_user=ostechnix ansible_port=2222

Group vars is same as host vars but the variables will be applied to the entire group instead of a single host. You can see from the above config, ansible_user, and ansible_port is the same for both the nodes. So you can create a group var where the variables will be inherited by all the nodes in the group. You need to add :vars to make the group as group vars.

[ubuntu]
managed1.anslab.com
managed2.anslab.com

[ubuntu:vars]
ansible_user=ostechnix
ansible_port=2222

Heads Up: When you have both group var and host var for the same node then host var takes high precedence.

There are many inventory parameters you can use and you can get the list from the official doc.

Inventory File With Alias

You can create an alias for the resource like below. Here m1 and m2 are aliases.

[ubuntu]
m1 ansible_host=managed1.anslab.com
m2 ansible_host=managed2.anslab.com

Now this alias can be used to run some tasks.

$ ansible m1 -m ping -o
m1 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": false,"ping": "pong"}
$ ansible m2 -m ping -o
m2 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": false,"ping": "pong"}

Inventory File In YAML Format

Inventory files can also be written in YAML format. Whatever we have discussed in previous sections is written in YAML format.

The below image represents two nodes with a couple of host variables.

Inventory With Host Vars
Inventory With Host Vars

Below image represents two nodes with group variables.

Inventory With Group Vars
Inventory With Group Vars

Ansible Inventory Command

Ansible has an inventory command which will be very helpful to view the inventory files information.

To get the list of supported options run the help command.

$ ansible-inventory --help

To get the inventory details in the graph format, use --graph flag. If you have different inventory files, you can use -i flag to explicitly point to the inventory file.

$ ansible-inventory --graph
Graph View
Graph View

You can print the host and group var information by passing --vars flag along with --graph flag.

$ ansible-inventory --graph --vars
Graph View With Vars
Graph View With Vars

When you use the --list flag, the output will be in JSON format.

$ ansible-inventory -list
JSON Output
JSON Output

You can get information about a particular node using the --host flag.

$ ansible-inventory --host managed1.anslab.com
Host Information
Host Information

Conclusion

In this article, we have seen an important concept that forms the core of ansible architecture. If you are a beginner, focus on building the inventory with ini format and down the line you will get to know more about best practices when you start working on production projects.

You May Also Like

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

This website uses cookies to improve your experience. By using this site, we will assume that you're OK with it. Accept Read More