Introduction to Inventories

Get introduced to Inventories and create your own.

You already have a way of inventorying your infrastructure. It might be:

  • By mentally remembering hostnames.
  • By grouping them by a standard naming convention.
  • With a custom database that stores specific properties about the hosts.
  • With a full-blown CMDB (configuration management database) that has entries for all the hosts.

Ansible codifies this information by using an inventory.

Inventories describe your infrastructure by listing hosts and groups of hosts. Using an inventory gives you the ability to share standard variables among groups. Inventories are also parsable with host patterns, giving you the ability to broadly or narrowly target your infrastructure with Ansible automation. In its simplest form, an Ansible inventory is a file.

Let’s suppose that, within an infrastructure, there are three web servers and a database server. The Ansible inventory might look like this.

Press + to interact
[webservers]
web01
web02
web03
[dbservers]
db01

Each host or group can be used for pattern matching or to define one or more variables.

Press + to interact
db01 database_name=customerdb

The above command creates a host variable named database_name with the value of customerdb. This variable is scoped to the host db01.

Press + to interact
[webserver:vars]
http_port=8080

The above snippet creates a group variable named http_port with the value of 8080, and it is shared among all three web servers.

Press + to interact
ansible webserver -i hosts -m ping

The above snippet uses the host pattern webserver to target all four web servers with the ping command.

Destroyed Infrastructure
In case you deleted the Ansible development environment, make sure to re-deploy the infrastructure for AWS and Azure by following the links.

Create an inventory

Converting the ad-hoc ping command to a playbook makes the task more repeatable. However, there are still some points of friction.

  1. Code duplication.

Each playbook contains the same set of variables used to connect to a Linux host.

Press + to interact
vars:
ansible_user: ansible
ansible_password: <Password>
ansible_ssh_common_args: '-o StrictHostKeyChecking=no'
  1. Passing the hostname or IP address to the -i option.
Press + to interact
ansible-playbook ping.yml -i <Public Ip Address>,

Both of these points of friction are eliminated by using an inventory.

Use an Ansible INI file as an inventory source

Let’s create an Ansible INI inventory for your Ansible development environment.

  1. Create a file named hosts; no file extension is required.

  2. Obtain the DNS name of the Linux virtual machine or EC2 instance.

    • The IP address can also be used.
  3. Add the DNS or IP name to the hosts file.

Press + to interact
#azure
vm-linuxweb001.eastus.cloudapp.azure.com
#aws
ec2-50-16-43-189.compute-1.amazonaws.com

Replace the example entry with the DNS name of your virtual machine or ec2 instance.

  1. Review and Run the ping.yml playbook using the hosts file.

Provide the actual DNS and IPs names for the Linux EC2 or VM instance below in the environment variables and the hosts file.

#azure 
vm-linuxweb001.eastus.cloudapp.azure.com 
#aws 
ec2-50-16-43-189.compute-1.amazonaws.com
ping.yml

Click on the Run button, wait for the environment to be set up, and execute the following command in the terminal:

Press + to interact
ansible-playbook ping.yml -i hosts

Ansible uses the host pattern of all in the playbook to match all the hosts in the hosts INI inventory and to execute the ping task against them.

Using an inventory makes running the playbook easier by eliminating the need to input the DNS name or IP address. However, the variables are still stored within the playbook.

Use host variables in an inventory

You will move the playbook variables to the hosts file.

  1. Open the hosts inventory.
  2. Add the ansible_user variable as a host var, replace the hostname.domain.com with your DNS name.
Press + to interact
hostname.domain.com ansible_user=ansible

Add a space after the DNS name, followed by the variable name. The variable is set by using an equal sign and the value of the variable.

  1. Add the ansible_password variable as a host var, replace <Password> with your password.
Press + to interact
hostname.domain.com ansible_user=ansible ansible_password=<Password>
  1. Add the ansible_ssh_common_args variable as a host var.
Press + to interact
hostname.domain.com ansible_user=ansible ansible_password=<Password>
ansible_ssh_common_args='-o StrictHostKeyChecking=no'
  1. Create a playbook called ping_novars.yml.

Review the hosts and ping_novars.yml files below:

Provide the actual DNS and IPs names for the Linux EC2 or VM instance below in the environment variables and the hosts file.

---
  - hosts: all
    
    tasks:
    - name: run ping
      ping:
ping_novars.yml
  1. Run the ping_novars.yml playbook using the hosts file.

Click on the Run button, wait for the environment to be set up, and execute the following command:

Press + to interact
ansible-playbook ping_novars.yml -i hosts

Try it now

Add the Windows virtual machine or EC2 instance to the hosts file.

  1. Open the hosts file.
  2. Obtain the DNS names for the Windows virtual machine or EC2 instance.
  3. Add the DNS name to a new line within the hosts file.
  4. Define hosts variables for connecting to the Windows host. Replace the <password> with the actual password.
Press + to interact
ansible_user=ansible
ansible_password=<Password>
ansible_winrm_server_cert_validation=ignore
ansible_connection=winrm
  1. Create a playbook called win_ping_novars.yml.
## Replace the example DNS names with the actual DNS names
## or IP Addresses
## Replace the password with actual password
#azure
vm-winweb001.eastus.cloudapp.azure.com ansible_user=ansible ansible_password=<Password> nsible_winrm_server_cert_validation=ignore ansible_connection=winrm ansible_winrm_transport=ntlm 

#aws
ec2-50-16-43-189.compute-1.amazonaws.com ansible_user=ansible ansible_password=<Password> nsible_winrm_server_cert_validation=ignore ansible_connection=winrm ansible_winrm_transport=ntlm
win_ping_novars.yml
  1. Run the win_ping_novars.yml playbook using the hosts file.
Press + to interact
ansible-playbook win_ping_novars.yml -i hosts
  1. Try adding the Linux host’s DNS name in the hosts file, re-execute the playbook, and observe.

MODULE FAILURE
fatal: [vm-linux*] MODULE FAILURE: /bin/sh: powershell: command not found.

Running the win_ping task against the Linux host fails because it is the wrong operating system.

  1. Run the win_ping_novars.yml with a limit, replace <WindowsHostDNSname>.
Press + to interact
# Replace the <WindowsHostDNSname> with the Windows host DNS name.
ansible-playbook win_ping_novars.yml -i hosts --limit <WindowsHostDNSname>

Solution
The solution to this challenge is provided in the Solution directory. Try it yourself first and compare your solution with the provided solution.

In this lesson, we introduced inventories, you created the INI inventory files, and refactored your playbooks to remove code duplication.

Get hands-on with 1300+ tech skills courses.