After outlining the initial installation and setup process in Ansible – Installing and Running (1) I’m continuing in this post with a more precise look at how to handle the main hosts file. Specifically how to lay it out and add host variables or group variables to the mix. Dynamic inventory assets and development/production inventory layouts are not covered here and only alluded to or linked to.
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 –
This file is completely configurable and can be expanded or broken up into multiple inventory files.
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:
[ ] 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.
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.
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:
usernamewould be replaced by the actual Ansible user on these hosts in the above.
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 –
- A host variable that then gives this name an IP address to refer to –
- Another host variable with the specific username like in the previous example –
- Then a final host variable that holds the custom SSH port to use when connecting to this host –
Here is what the layout looked like for this file:
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
When put together using a group named “webservers” this makes –
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:
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:
To add group variables to this new group of a group, the new name is added to yet another group with the standard
Like at the bottom of this code snippet:
The concept of grouping groups into more groups can theoretically go on indefinitely. Another level of grouping is added below to demonstrate:
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
/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:
Will apply to any hosts located in the
webservers group. These variable files are written in YAML.
Similarly, any host variables defined in:
Are applied to the host named
server-name-1 from the original
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.