Inventory management is an essential part of any organization’s operations. Ensuring that the right items are available when they are needed is crucial to ensuring efficient workflows and minimizing waste. This article provides a comprehensive guide to inventory concepts, outlining the different types of inventory and how they can be used to improve your organization’s efficiency. Ansible is a powerful automation tool that can be used to manage inventory in a variety of ways. In this article, we will discuss three Ansible inventory concepts: static inventory, dynamic inventory, and role-based access control (RBAC). We will also provide examples of how each type of inventory can be used in practice. Static Inventory: A static inventory is a list of items that are always present in an organization’s possession or storage. This type of inventory is useful for situations where you know the exact quantity and type of items that are required, and you do not need to track changes over time. For example, a company might maintain a static inventory of office supplies on site so that employees always have the necessary supplies available. Dynamic Inventory: A dynamic inventory is an ongoing list of items that are constantly being added or removed from an organization’s possession or storage. This type of inventory is useful for situations where you need to track changes over time but do not have access to the original list of items. For example, a company might maintain a dynamic inventory of products in stock so that managers can keep track of changes over time and make decisions based on current information rather than outdated data. Role-Based Access Control (RBAC): RBAC allows administrators to assign specific roles within an organization to specific users, allowing them limited access to specific parts or all parts of an organization’s infrastructure. This type of security allows administrators to enforce policies without having to grant everyone unrestricted access to all systems within an organization. For example, administrators could use RBAC restrictions to allow employees only ..
Lastly splitting up the variable types and their definitions into their own YAML files is briefly introduced in the final step, and works best for more complex network hierarchies.
1 – Hosts Inventory File
As shown in “Ansible – Installing and Running (1)” Ansible operates by working simultaneously with multiple hosts in your infrastructure. It’s preferred way of doing this is to allocate hosts into different groups inside of the inventory file – /etc/ansible/hosts
1 – Hosts Inventory File2 – Hosts and Groups3 – Host and Group Variables4 – Groups of Groups5 – Multiple Inventory Files
[alert-announce]
$ ls /etc/ansible/ ansible. cfg hosts hosts. orig roles
[/alert-announce]
This file is completely configurable and can be expanded or broken up into multiple inventory files.
[alert-announce]
$ sudo vim /etc/ansible/hosts
[/alert-announce]
There’s a special form of inventory in Ansible known as dynamic inventory that refers to inventory files or asserts that get pulled down from the cloud, or other server-side sources. This is not covered in this post, however.
2 – Hosts and Groups
As seen in the first post, the INI style formatting for an Ansible hosts file looks similar to this:
[alert-announce]
/etc/ansible/hosts
[webservers] webremote. one. ip. address webremote. two. ip. address webremote. three. ip. address [dbservers] dbremote. one. ip. address dbremote. two. ip. address dbremote. three. ip. address
[/alert-announce]
Square brackets [ ] contain a group name which is used to decide what systems you are controlling at what times and for what purpose. This makes it possible to apply actions to specific nodes/hosts as and when necessary.
Also systems (nodes/hosts) can be attributed under more than one group if needed, so in the snippet above one of the example nodes could be both a web server and a database server, added to both group entries in the file.
The hostnames can also be domain names instead of raw IP addresses if preferred, and when adding a large numbers of hosts if the domain names follow a similar numerical pattern, you can use ranges of numbers instead of adding them all individually.
[alert-announce]
/etc/ansible/hosts
[webservers] www[01:50]. example. com
[/alert-announce]
Lastly, hosts that run on non-standard SSH ports i.e. not 22 must have their custom SSH port numbers inserted after the hostname separated by a colon.
For example:
webremote.one.ip.address:3675
Or instead defined through host/group variables (see next step).
3 – Host and Group Variables
Variables in the inventory file(s) are set on a host basis or group basis. There are many of these inbuilt variables on offer to the user when constructing the file.
Here is an example of two host variables, that explicitly tell Ansible to use SSH as the connection type, with a set username:
[alert-announce]
/etc/ansible/hosts
[webservers] webremote. one. ip. address ansible_connection=ssh ansible_user=username webremote. two. ip. address ansible_connection=ssh ansible_user=username webremote. three. ip. address ansible_connection=ssh ansible_user=username [dbservers] dbremote. one. ip. address ansible_connection=ssh ansible_user=username dbremote. two. ip. address ansible_connection=ssh ansible_user=username dbremote. three. ip. address ansible_connection=ssh ansible_user=username
[/alert-announce]
In the first post on Ansible I laid out these host variables and the file formatting differently, by using:
An “empty” name for the hosts – server-name-1 A host variable that then gives this name an IP address to refer to – ansible_host=remote. one. ip. address Another host variable with the specific username like in the previous example – ansible_user=username Then a final host variable that holds the custom SSH port to use when connecting to this host – ansible_port=3980
Here is what the layout looked like for this file:
[alert-announce]
/etc/ansible/hosts
[servers] server-name-1 ansible_host=remote. one. ip. address ansible_user=username ansible_port=3980 server-name-2 ansible_host=remote. one. ip. address ansible_user=username ansible_port=3980 server-name-3 ansible_host=remote. one. ip. address ansible_user=username ansible_port=3980
[/alert-announce]
Group variables allow extra options and settings like in the above to be applied to an entire group at once. Instead of having to set the same variables for each host when the value of the variables is the same.
These are defined by creating a new set of square brackets [ ] that contain the group name you wish to apply the variables to, followed by a tag that consists of a : and the term vars .
When put together using a group named “webservers” this makes – [webservers:vars]
The variables you want to apply to the group are then listed on separate lines – an example of all of this is shown in the below code snippet:
[alert-announce]
/etc/ansible/hosts
[webservers] webremote. one. ip. address webremote. two. ip. address webremote. three. ip. address [webservers:vars] ansible_user=username ansible_port=3980 ntp_server=ntp. example. com proxy=proxy. example. com [dbservers] dbremote. one. ip. address dbremote. two. ip. address dbremote. three. ip. address [dbservers:vars] ansible_user=username ansible_port=3980 ntp_server=ntp. example. com proxy=proxy. example. com
[/alert-announce]
4 – Groups of Groups
There’s a further way of making “groups out of groups” by using the :children tag. These can have group variables applied to them too by using the same method in the last step. To do this extra grouping, a new group name is created then suffixed with the :children tag which will contain the original groups defined.
Such as here:
[alert-announce]
/etc/ansible/hosts
[webservers-one] webremote. one. ip. address webremote. two. ip. address webremote. three. ip. address [dbservers-one] dbremote. one. ip. address dbremote. two. ip. address dbremote. three. ip. address [cluster-one:children] webservers-one dbservers-two
[/alert-announce]
To add group variables to this new group of a group, the new name is added to yet another group with the standard :vars tag.
Like at the bottom of this code snippet:
[alert-announce]
/etc/ansible/hosts
[webservers-one] webremote. one. ip. address webremote. two. ip. address webremote. three. ip. address [dbservers-one] dbremote. one. ip. address dbremote. two. ip. address dbremote. three. ip. address [cluster-one:children] webservers-one dbservers-two [cluster-one:vars] ansible_user=username ansible_port=3980 ntp_server=ntp. example. com proxy=proxy. example. com
[/alert-announce]
The concept of grouping groups into more groups can theoretically go on indefinitely. Another level of grouping is added below to demonstrate:
[alert-announce]
/etc/ansible/hosts
[webservers-one] webremote. one. ip. address webremote. two. ip. address webremote. three. ip. address [dbservers-one] dbremote. one. ip. address dbremote. two. ip. address dbremote. three. ip. address [cluster-one:children] webservers-one dbservers-two [cluster-one:vars] ansible_user=username ansible_port=3980 ntp_server=ntp. example. com proxy=proxy. example. com [webservers-two] webremote. one. ip. address webremote. two. ip. address webremote. three. ip. address [dbservers-two] dbremote. one. ip. address dbremote. two. ip. address dbremote. three. ip. address [cluster-two:children] webservers-two dbservers-two [cluster-two:vars] ansible_user=username ansible_port=3980 ntp_server=ntp. example. com proxy=proxy. example. com [all-clusters:children]cluster-one cluster-two
[/alert-announce]
More realistically this could be seen in terms of grouping local data-centre hosts into regions and then into a country wide group.
5 – Multiple Inventory Files
The singular /etc/ansible/hosts file is fine for smaller more contained network setups, but the preferred practice in Ansible is not to store variables in the main hosts inventory file. At least when dealing with larger more complex layouts of hosts, or bigger networks.
Host and group variables ideally when handling large scale setups should be stored in individual files. Files that are relative to the main inventory file.
As an example any group variables defined in the below file:
[alert-announce]
/etc/ansible/group_vars/webservers. yml
[/alert-announce]
Will apply to any hosts located in the webservers group. These variable files are written in YAML.
Similarly, any host variables defined in:
[alert-announce]
/etc/ansible/host_vars/server-name-1. yml
[/alert-announce]
Are applied to the host named server-name-1 from the original hosts file.
Further segmentation and organization of the host/inventory files is followed but not covered in this post, see Multistage Environments with Ansible for more information on how this is done.
A future third post on Ansible will describe the modules in place that can be run as part of a playbook, or as ad-hoc based commands.