Bookmark this page

Chapter 2. Implementing an Ansible Playbook

Abstract

Goal Create an inventory of managed hosts, write a simple Ansible Playbook, and run the playbook to automate tasks on those hosts.
Objectives
  • Describe Ansible inventory concepts and manage a static inventory file.

  • Describe where Ansible configuration files are located, how Ansible selects them, and edit them to apply changes to default settings.

  • Write a basic Ansible Playbook and run it using the automation content navigator.

  • Write a playbook that uses multiple plays with per-play privilege escalation, and effectively use automation content navigator to find new modules in available Ansible Content Collections and use them to implement tasks for a play.

Sections
  • Building an Ansible Inventory (and Guided Exercise)

  • Managing Ansible Configuration Files (and Guided Exercise)

  • Writing and Running Playbooks (and Guided Exercise)

  • Implementing Multiple Plays (and Guided Exercise)

Lab
  • Implementing an Ansible Playbook

Building an Ansible Inventory

Objectives

  • Describe Ansible inventory concepts and manage a static inventory file.

Defining the Inventory

An inventory defines a collection of hosts that Ansible manages. These hosts can also be assigned to groups, which can be managed collectively. Groups can contain child groups, and hosts can be members of multiple groups. The inventory can also set variables that apply to the hosts and groups that it defines.

There are two ways to define host inventories. Use a text file to define a static host inventory. Use an Ansible plig-in to generate a dynamic host inventory as needed, using external information providers.

Specifying Managed Hosts with a Static Inventory

A static inventory file is a text file that specifies the managed hosts that Ansible targets. You can write this file using a number of different formats, including INI-style or YAML. The INI-style format is very common and is used for most examples in this course.

Note

Ansible supports multiple static inventory formats. This section focuses on the most common one, the INI-style format.

In its simplest form, an INI-style static inventory file is a list of hostnames or IP addresses of managed hosts, each on a single line:

web1.example.com
web2.example.com
db1.example.com
db2.example.com
192.0.2.42

Normally, however, you organize managed hosts into host groups. Host groups allow you to more effectively run Ansible against a collection of systems. In this case, each section starts with a host group name enclosed in square brackets ([]). This is followed by the hostname or an IP address for each managed host in the group, each on a single line.

In the following example, the host inventory defines two host groups: webservers and db-servers.

[webservers]
web1.example.com
web2.example.com
192.0.2.42

[db-servers]
db1.example.com
db2.example.com

Hosts can be in multiple groups. In fact, the recommended practice is to organize your hosts into multiple groups, possibly organized in different ways depending on the role of the host, its physical location, whether it is in production or not, and so on. This allows you to easily apply Ansible plays to specific sets of hosts based on their characteristics, purpose, or location.

[webservers]
web1.example.com
web2.example.com
192.0.2.42

[db-servers]
db1.example.com
db2.example.com

[east-datacenter]
web1.example.com
db1.example.com

[west-datacenter]
web2.example.com
db2.example.com

[production]
web1.example.com
web2.example.com
db1.example.com
db2.example.com

[development]
192.0.2.42

Important

Two host groups always exist:

  • The all host group contains every host explicitly listed in the inventory.

  • The ungrouped host group contains every host explicitly listed in the inventory that is not a member of any other group.

Defining Nested Groups

Ansible host inventories can include groups of host groups. This is accomplished by creating a host group name with the :children suffix. The following example creates a new group called north-america, which includes all hosts from the usa and canada groups.

[usa]
washington1.example.com
washington2.example.com

[canada]
ontario01.example.com
ontario02.example.com

[north-america:children]
canada
usa

A group can have both managed hosts and child groups as members. For example, in the previous inventory you could add a [north-america] section that has its own list of managed hosts. That list of hosts would be merged with the additional hosts that the north-america group inherits from its child groups.

Simplifying Host Specifications with Ranges

You can specify ranges in the hostnames or IP addresses to simplify Ansible host inventories. You can specify either numeric or alphabetic ranges. Ranges have the following syntax:

[START:END]

Ranges match all values from START to END, inclusively. Consider the following examples:

  • 192.168.[4:7].[0:255] matches all IPv4 addresses in the 192.168.4.0/22 network (192.168.4.0 through 192.168.7.255).

  • server[01:20].example.com matches all hosts named server01.example.com through server20.example.com.

  • [a:c].dns.example.com matches hosts named a.dns.example.com, b.dns.example.com, and c.dns.example.com.

  • 2001:db8::[a:f] matches all IPv6 addresses from 2001:db8::a through 2001:db8::f.

If leading zeros are included in numeric ranges, they are used in the pattern. The second example above does not match server1.example.com but does match server07.example.com. To illustrate this, the following example uses ranges to simplify the [usa] and [canada] group definitions from the preceding example:

[usa]
washington[1:2].example.com

[canada]
ontario[01:02].example.com

Verifying the Inventory

When in doubt, use the ansible-navigator inventory command to verify a machine's presence in the inventory. In the following example, ansible-navigator inventory is run in stdout mode. The first query matches a host in the inventory, and the second does not.

[user@controlnode ~]$ ansible-navigator inventory -m stdout \
> --host washington1.example.com
{}
[user@controlnode ~]$ ansible-navigator inventory -m stdout \
> --host washington01.example.com
[WARNING]: Could not match supplied host pattern, ignoring: washington01.example.com
...output omitted...

The following command lists all hosts in the inventory.

[user@controlnode ~]$ ansible-navigator inventory -m stdout --list
{
    "_meta": {
        "hostvars": {}
    },
    "all": {
        "children": [
            "canada",
            "ungrouped",
            "usa"
        ]
    },
    "canada": {
        "hosts": [
            "ontario01.example.com",
            "ontario02.example.com"
        ]
    },
    "usa": {
        "hosts": [
            "washington1.example.com",
            "washington2.example.com"
        ]
    }
}

The following command lists all hosts in a group.

[user@controlnode ~]$ ansible-navigator inventory -m stdout --graph canada
@canada:
  |--ontario01.example.com
  |--ontario02.example.com

Run the ansible-navigator inventory command to interactively browse inventory hosts and groups:

[user@controlnode ~]$ ansible-navigator inventory
  Title             Description
0│Browse groups     Explore each inventory group and group members members
1│Browse hosts      Explore the inventory with a list of all hosts

Type :0 to select "Browse Groups":

  Name                                Taxonomy                         Type
0│canada                              all                              group
1│ungrouped                           all                              group
2│usa                                 all                              group

Press the ESC key to exit the Groups menu. Type :1 to select "Browse Hosts"

  Inventory hostname
0│ontario01.example.com
1│ontario02.example.com
2│washington1.example.com
3│washington2.example.com

Press the ESC key twice to exit ansible-navigator inventory.

Important

If the inventory contains a host and a host group with the same name, the ansible-navigator inventory command prints a warning.

Ensure that host groups do not use the same names as hosts in the inventory.

Overriding the Location of the Inventory

The /etc/ansible/hosts file is considered the system's default static inventory file. However, normal practice is not to use that file but to specify a different location for your inventory files.

The ansible-navigator commands that you use to run playbooks can specify the location of an inventory file on the command line with the --inventory PATHNAME or -i PATHNAME option, where PATHNAME is the path to the desired inventory file.

Note

You can also define a different default location for the inventory file in your Ansible configuration file.

Dynamic Inventories

Ansible inventory information can also be dynamically generated, using information provided by external databases. The open source community has written a number of dynamic inventory plug-ins that are available from the upstream Ansible project. If those Ansible plug-ins do not meet your needs, you can also write your own.

For example, a dynamic inventory program could contact your Red Hat Satellite server or Amazon EC2 account, and use information stored there to construct an Ansible inventory. Because the program does this when you run Ansible, it can populate the inventory with up-to-date information provided by the service as new hosts are added, and old hosts are removed.

How to use a dynamic inventory is beyond the scope of this section.

Revision: rh294-9.0-c95c7de