Understanding Ansible Inventories

Eddie Knight
FAUN — Developer Community 🐾
6 min readApr 8, 2019

The key to understanding all of Ansible.

Ansible has been designed to make automation human-readable. Everything about an Ansible playbook is designed to be simple to understand even for less-technical users.

Ansible inventories, however, are not quite as intuitive.

Inventories are the key to assigning human-readable names to various hosts. They’re also the key to targeting multiple hosts simultaneously for a particular playbook, while optionally excluding others.

Once you understand inventories, you’ll be significantly better equipped to read and write Ansible playbooks.

Before I jump into explaining the inventory, however, I want to display the simple beauty of the inventory.

The simple beauty of the inventory:

In my development directory, I have several different directories: saas, paas, hosts, and more. Inside of saas and paas I have countless playbooks that target hosts all across our infrastructure on both the public and private cloud. In hosts I have a compendium of every host name on our infrastructure.

In spite of the massive list of hosts, I can tell my playbook to target one type of servers specifically. Here is an example from my Mattermost automated build script:

- name: Set up Logging and Monitoring
hosts: mattermost
gather_facts: yes
become: yes
connection: ssh
serial: -1
roles:
- { role: '../../paas/rhel/roles/logging', tags: 'logs' }
- { role: '../../paas/rhel/roles/nrpe', tags: 'nrpe' }
- name: Configure Mattermost App Servers
hosts: mattermost_app
gather_facts: yes
become: yes
connection: ssh
serial: -1
roles:
- role
- name: Configure Mattermost Proxy Servers
hosts: mattermost_proxy
gather_facts: yes
become: yes
connection: ssh
serial: -1
roles:
- { role: '../nginx/role', tags: 'nginx' }

The real power here is in the hosts: lines, where I target each of my different types of servers.

In order to enable a high availability cluster, I have three app servers and three proxy servers. I am also setting up monitoring and logging on all of those servers (plus the additional database cluster which isn’t mentioned in this section of the code).

Host Groups:

Groups enable me to target the app, database, and proxy servers separately or all together. Those groups are defined in the inventory, and point to individual host names.

Each of these hostnames is handled by another script to translate it to an IP address. I won’t get into that here. You may want to simply write in IP addresses here instead of hostnames.

# hosts/mattermost[mattermost_app]
mattermost-app-[01:03]
[mattermost_proxy]
mattermost-proxy-[01:03]
[mattermost_db]
mattermost-db-[01:03]
[mattermost:children]
mattermost_app
mattermost_proxy
mattermost_db

In this file I have nine different hostnames. [01:03] is just shorthand for repeating the same thing three times, with 01, 02, and 03. This is exactly the same as writing the name out three times. I am showing you here just so that you can use the trick if it’s helpful for you.

Because this part can be confusing at times, I’m going to allow this particular explanation to take up a bit of space. No apologies.

mattermost_app has three hosts:

  • mattermost-app-01
  • mattermost-app-02
  • mattermost-app-03

mattermost_db has three hosts:

  • mattermost-db-01
  • mattermost-db-02
  • mattermost-db-03

mattermost_proxy has three hosts:

  • mattermost-proxy-01
  • mattermost-proxy-02
  • mattermost-proxy-03

The mattermost group is different in that it holds the children of other groups. Because of this, the mattermost group has all nine of the above hosts.

Usage:

When initiating the Ansible playbook, I am able to tell it where this inventory file is. Here’s the command I would type into my CLI for this example:

ansible-playbook -i hosts/mattermost saas/mattermost/build.yml

The -i command provides the inventory to the script that is provided in the next parameter.

The -i command is part of the beauty of inventories. One playbook can be used in a variety of ways by passing a different inventory when you run the script. Gorgeous!

At this point your inventory is functional. Your hostnames are ready for use, and don’t need anything more to function. However, it is common to use inventories to manage variables.

How Variables Work

I suggest looking at the in-depth documentation of Ansible Variables if this isn’t intuitive to you.

In short, the variables use Jinja2. After a variable is defined using a task or the inventory, it can be accessed virtually anywhere in your playbooks by putting the variable name inside double mustaches like this: {{ foo }}

Group Variables:

Because each of my hosts are going to be treated the same as others in their group, I can utilize Ansible inventory group variables.

To create group variables, I will create a directory to hold all of them. Ansible looks for this directory at the same level as the file I provided as the inventory (“beside” it in the directory). This directory should be named group_vars.

Inside of group_vars/ I will create a file containing any variables that are needed by those groups.

I can create group variables for mattermost_db_01, mattermost_db_02, and mattermost_db_03, in two ways. I can create variables in my hosts/group_vars/mattermostfile, or I can do it in hosts/group_vars/mattermost_db.

Here is a small example from my inventory:

# hosts/group_vars/mattermost_dbprefix: dev
os_flavor: 'm8.c2'
os_security_groups: "default,{{prefix}}_mm_db,{{prefix}}_admin,{{prefix}}_nrpe"
os_network: {{ prefix }}_01

Notice that I can use a variable immediately after it’d defined. I use this as a handy little trick to reduce the differences between dev and prod inventories.

If I create variables in the mattermost_db file, the variables will not be present for any plays that target mattermost, mattermost_app, or mattermost_proxy.

However, because mattermost_db is a child of mattermost, any variables I create in hosts/group_vars/mattermost will be available to mattermost_db.

Again for extreme clarity, my inventory files at this point are:

  • hosts/mattermost
  • hosts/group_vars/mattermost
  • hosts/group_vars/mattermost_app
  • hosts/group_vars/mattermost_db
  • hosts/group_vars/mattermost_proxy

Host Variables

This is my last piece of information for you, because it’s a feature that I rarely use.

Host variables work exactly like group variables, but targeting a single host.

Continuing the previous example, let’s imagine that I need to treat one of my app servers differently for some reason. In that case, I can add a new directory called host_vars and then add a file to target the single host by name.

# hosts/host_vars/mattermost_app_01os_flavor: 'm16.c4'

Now I have a different OS flavor for one of my app servers. The others in the same group will receive their os_flavor variable from hosts/group_vars/mattermost_app.

Hosts without groups:

This is a good opportunity for me to let you know that you don’t have to put a host in a group. Let’s revise the previous example to use one of each type of server (instead of three of each).

# hosts/mattermostmattermost-app
mattermost-proxy
mattermost-db
[mattermost]
mattermost_app
mattermost_proxy
mattermost_db

Now you can see that I have only one group, which contains three hosts.

Each of those hosts can have an entry in hosts/host_vars/ and they can be targeted by variables in hosts/group_vars/mattermost, but that is the only group in this example.

Conclusion

Now that you have this information, go look at some playbooks with fresh eyes. If you’re anything like me, you’ll have a big “Aha!” moment.

Tell me whether I should write more content like this by holding down the applause button or leaving a comment below!

Follow us on Twitter 🐦 and Facebook 👥 and join our Facebook Group 💬.

To join our community Slack 🗣️ and read our weekly Faun topics 🗞️, click here⬇

If this post was helpful, please click the clap 👏 button below a few times to show your support for the author! ⬇

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in FAUN — Developer Community 🐾

We help developers learn and grow by keeping them up with what matters. 👉 www.faun.dev

Written by Eddie Knight

Senior Consultant at Citihub & Developer Advocate for Probr

No responses yet

What are your thoughts?