Ansible Quick Start Guide
上QQ阅读APP看书,第一时间看更新

Ansible inventory

Ansible host management is simpler by far than all other configuration management and orchestration tools. It is basically a simple .ini file that contains a list of IP addresses, fully qualified hostnames, or short hostnames of the host clients. It also sometimes contains extra variables that define some aspects about the hosts. Generally, hosts are organized in groups with the name of the group put on top between two square brackets, such as [Group1].

Adding a new host is as easy and simple as adding a new line to the host file, making sure it is in the right group and that it has the right variables needed to manage it.

In the default Ansible configuration file, the inventory file is located at /etc/ansible/hosts. It is an .ini file with simple text and a basic structure composed of sections, properties, and values. Being the default location, however, does not make it the best. In many cases, Ansible can be used by non-root users who do not have the privileges to edit files located outside their home directory. Our recommendation for such an environment is to have all Ansible configuration files located in a folder within the home directory of the user. This means that these users can alter their configuration to accommodate their needs. Other than changing the Ansible configuration file to point to a different inventory location, we can also choose an inventory file while executing either an Ansible ad hoc command or a playbook by adding the -i option, followed by the location of the inventory file:

sudo nano /etc/ansible/ansible.cfg
inventory = /home/user1/ansible/hosts

Or, we can use the following

ansible -m ping -i ~/ansible/hosts

The Ansible inventory does not just serve to arrange alike hosts; it is also much more useful when orchestrating tasks. Having several hosts that provide the same type of service (such as web servers, database controllers, or Web APIs) grouped in one group allows for a smarter and more efficient group control. A good host classification means that you can be more precise when applying fixes or optimizations to a specific service. Hosts can be part of multiple groups to allow them to answer to each task that is sent toward each specific aspect that they possess:

[webserver]
192.168.10.10
192.168.10.12

[mysqldb]
192.168.10.10
192.168.10.20

[fileserver]
192.168.10.11
192.168.10.20

There are two types of inventory in Ansible: static and dynamic. In a small to medium environment or infrastructure, a static inventory should do just fine. However, when there is a very large number of hosts, the tasks can get complicated and errors may start to arise. A dynamic inventory relies on a third-party service, such as AWS EC2, Rackspace, and OpenStack, to provide it with its inventory. There is always the possibility of scripting your way through and filling your Ansible static host inventory files, which can be handy if you know what you are doing.

When adding hosts with a similar pattern to an Ansible inventory file, we can simplify its syntax by changing the different pattern with a counter block, as in the following examples.

This is the original inventory:

[servers]
node0.lab.edu
node1.lab.edu
node2.lab.edu
node3.lab.edu
node4.lab.edu

This is the simplified inventory:

[servers]
Node[0:4].lab.edu
This inventory syntax is not limited to numbers in specific formats. It can also be used for alphabetic enumeration, that is,  [a:z] or [A:Z], or numbers with specific digits, such as  [001:250]. It can be placed at any location in the hostname.

First let's talk about the Ansible static inventory. As its name implies, it is a static host organisation in a text file. By default, it is an .ini file that is very simply structured in lines with values:

node0.lab.edu

[lab1servers]
node1.lab.edu
node2.lab.edu

[lab2servers]
node3.lab.edu

 Alternatively, it can be a YAML file, structured like a Python script structure:

all:
hosts:
node0.lab.edu
children:
lab1servers:
hosts:
node1.lab.edu
node2.lab.edu
lab2server:
hosts:
node3.lab.edu
Most of our inventory examples will be written in the  .ini file format. While the YAML format looks prettier and neater, it is easier and faster to write in . ini format.

A host inventory should be tolerant to all kinds and shapes of hosts. The Ansible inventory can accommodate these differences by introducing host and group variables. This is basically a way of defining each host or group with a certain aspect to help Ansible with its management. Host variables are very specific to the host and can only affect that host. The most commonly defined host variables are as follows:

  • ansible_user: This value defines which user Ansible will be using to manage the host. It has the same function as the -u option, which is used in the ad hoc command.
  • ansible_host: Some hosts may not be located in the DNS server, or we may want to give them different names. This variable allows us to point to the IP address of the host without checking how we choose to name it in the inventory.
  • ansible_port: This is also known as host1:port. This is used when the hosts are accessible via a certain port other than the default.
  • ansible_connection: This varies between ssh, the default connection; local, to communicate with the local machine; and docker, for running commands directly in Docker containers that rely on the local machine's Docker client. We will cover Ansible Docker usage in more detail in Chapter 8, Ansible Advanced Features.
  • ansible_become: This option, when present, forces the host to execute all the commands on an elevated privilege (sudo).
  • ansible_become_user: This allows Ansible to run a command as a specific user other than the remote access user.
  • ansible_ssh_pass: This specifies the password to be used to access the host. This is not recommended, since the user's password will be written in plain text. The next option is better.
  • ansible_ssh_private_key_file: This option specifies the location of the private SSH key to be used to access this VM. This is much more secure than writing the password in plain text.

This is a sample configuration:

ansibleserv ansible_connection: local fileserver
ansible_host: 192.168.10.10 ansible_port:22
node1.lab.edu ansible user: setup
ansible_ssh_private_key:/home/user/node1.key
node2.lab.edu ansible_become: yes
ansible_become_user: user1

Some host variables can be defined under the group flag, especially when the hosts share the same admin username or SSH key. The group-specific variables are defined in the same way as the host variable, in a very simple text format. Group variables, however, have an extra feature: they can be defined in two ways, either on the inventory file or on separate files. By default, Ansible looks for them in the /etc/ansible/group_vars/ folder.

Defining group variables in the inventory file should look like the following:

[labserver]
node0.lab.edu
node1.lab.edu

[labserver:vars]
ansible_connection=ssh
ansible_port=22
When running a task on a single host, or a part of a group that has its variables defined, those variables will be applied to the host as if they are host variables.

Host groups can also be organized into groups using the :children suffix in .ini files and the children: entry in the YAML files. This is how it looks in an INI format:

[webservers]
node0.lab.edu
node1.lab.edu

[fileserver]
node2.lab.edu
node3.lab.edu

[server:children]
webservers
fileserver

Any variable applied to the parent group will get flattened to the hosts of each sub-group or child group. However, the variable of the sub-group overrides the parent variables:

[servers:vars]
ansible_user=setup
ansible_private_ssh_key=/home/user/ansible.key

The method recommended by Ansible is to define the group variables by storing them away from the inventory file and in the group_vars folder in separate YAML or JSON files. We will mainly be using the YAML format for the group variables file, as shown here:

/etc/ansible/group_vars/webserver
/etc/ansible/group_vars/fileserver

Each file will look as follows:

---
ansible_user=setup
ansible_private_ssh_key=/home/user/ansible.key

Hosts can also have their variables stored in a YAML file. By default, this is located in the /etc/ansible/host_vars/ folder. They share the same structure as the group variable files.

Variables defined in the playbook directory override those in the inventory directory. We will look closely at the playbook directory in the next section.

Ansible also supports importing an inventory from other third-party frameworks, such as cloud providers, LDAP servers, or Cobbler. For each of these, there is a specific import script that needs to be executed with Ansible after the -i option for inventory selection. This starts the communication between Ansible and the third-party API that returns the inventory list. The execution should happen after filling in an .ini file with the appropriate parameters of the third-party server or API.