Ansible, an open-source IT automation engine, streamlines tasks across IT environments, enhancing scalability, consistency, and reliability. Ansible is versatile, performing three main tasks: setting up servers (provisioning), adjusting settings and managing services (configuration management), and automating application deployment. It's popular for automating tasks on servers, virtual machines, and in the cloud. Ansible can configure various systems, including databases, storage, networks, and firewalls.
What Is an Ansible Inventory File?
In Ansible, managing a large number of remote servers can be challenging. To ease this process, you can group and target your servers using a special file called the “ansible inventory file”. This file helps organize your servers into logical groups, making it easier to apply configurations or execute commands across specific sets of servers.
The Ansible inventory file serves as a tracking tool for system administrators to manage their remote systems. By default, Ansible uses the Ansible host file located in the /etc/ansible directory to list all managed remote nodes. However, Ansible offers flexibility, allowing users to create custom inventory files tailored to their needs. This is particularly useful in complex environments where segregating managed nodes into separate inventory files is preferred over the default Ansible host file setup.
In this tutorial, we'll walk through installing Ansible on Ubuntu 22.04 and configuring a custom Ansible inventory file on the control node.
Prerequisites
To set up the Ansible inventory file, you need the following prerequisites:
- An Ansible control node: This should be a machine running Ubuntu 22.04, where Ansible is installed and properly configured to connect to the Ansible hosts using SSH keys. It's essential to have a standard user with sudo privileges on this node and ensure that the firewall is enabled following standard server setup procedures.
- Managed nodes / Ansible Hosts: These are remote servers running Ubuntu 22.04 that will be managed by Ansible. You should have at least two of these servers set up and accessible from the control node via SSH.
How to Install Ansible on Ubuntu 22.04?
First, you will install Ansible on the control node. To install Ansible on the control node and set up a passwordless SSH connection with remote hosts, follow these steps:
Step 1: Install Ansible
Log in to your control node via SSH or a terminal and update the system package lists using the following command:
$ sudo apt update
To install Ansible and its dependencies, use the below command:
$ sudo apt install -y ansible
Step 2: Verify Ansible Installation
Check the Ansible version to ensure successful installation:
$ ansible --version
Step 3: Configure Inventory File
Open the default inventory file using a text editor:
$ sudo nano /etc/ansible/hosts
By default, the file contains comments and examples. You can specify hostnames or IP addresses and group them as needed.
Step 4: Generate SSH Key Pair
Generate an SSH key pair on the control node:
$ ssh-keygen
The above command creates a public and private key pair stored in the ~/.ssh/ directory.
Step 5: Copy the Public Key to Remote Hosts
Use ssh-copy-id to copy the public key to each remote host:
ssh-copy-id user@remote_host_ip
Replace the user with your username and remote_host_ip with the IP address of the remote host.
Enter the password for the remote host when prompted.
Step 6: Verify Passwordless SSH Connection
Test the SSH connection to the remote host without entering a password:
$ ssh user@remote_host_ip
You should be able to log in without being prompted for a password.
If you have additional hosts then repeat the process for Additional Hosts. Repeat steps 5 and 6 for each additional remote host, ensuring that you can SSH into each one without a password.
By completing these steps, you'll have installed Ansible on your control node and established a passwordless SSH connection with your remote hosts, allowing seamless communication for Ansible automation tasks.
How to Create a Custom Ansible Inventory File?
To create a custom inventory file for managing multiple nodes in separate projects in Ansible, follow these steps:
Step 1: Create Project Directory
Open a terminal and create a directory for your project. For example, let’s say you want to create a project directory named “ansible”:
$ mkdir ansible && cd ansible
Step 2: Create an Inventory File
Within the project directory, create a simple text file for your inventory:
$ sudo nano inventory
You can name the file arbitrarily.
Step 3: Add Managed Nodes
In the ansible inventory file, list the IP addresses of your managed nodes, each on a separate line:
192.168.1.6
198.148.1.5
Add more nodes as needed. After adding hosts, save your changes and exit the text editor.
Step 4: Verify Managed Hosts
Confirm that your managed hosts are listed correctly using the Ansible inventory command:
$ ansible-inventory -i ansible/inventory --list
Ensure to reference the full path to the inventory file with the -i option.
Step 5: Execute Tasks With Custom Inventory
With the custom inventory file created, you can now execute Ansible tasks or playbooks targeting the managed hosts:
$ sudo ansible -i ansible/inventory -m ping all
Replace -m ping with any other Ansible module or specify a playbook to run against the hosts listed in your custom inventory file.
By following these steps, you'll effectively organize and manage your Ansible inventory by creating separate inventory files for different projects, simplifying resource tracking and collaboration among sysadmins.
Organizing Servers Into Groups and Subgroups in the Ansible Inventory File
To organize nodes into groups and sub-groups in Ansible for better inventory management, follow these steps:
Step 1: Grouping Servers
In the inventory file, organize servers into different groups and subgroups for better management. This practice not only keeps hosts organized but also enables the use of group variables, which is useful for managing multiple staging environments with Ansible.
[webservers]
192.168.1.6
192.168.1.5
[dbservers]
192.168.1.7
server_hostname
[development]
192.168.1.5
192.168.1.7
[production]
192.168.1.5
server_hostname
Step 2: Using Metagroups
You can aggregate multiple groups as children under a "parent" group, creating a metagroup. This allows for a more granular arrangement.
Example:
[web_dev]
192.168.1.6
[web_prod]
192.168.1.5
[db_dev]
192.168.1.7
[db_prod]
server_hostname
[webservers:children]
web_dev
web_prod
[dbservers:children]
db_dev
db_prod
[development:children]
web_dev
db_dev
[production:children]
web_prod
db_prod
Step 4: Enhancing Targeting
Break down groups or create alternative arrangements to target smaller groups of servers as needed, particularly as your server count grows.
How to Set up Host Aliases in Ansible Inventories?
Employ aliases to name servers for easier reference when executing commands and playbooks.
Include a variable named ansible_host after the alias name, containing the corresponding IP address or hostname of the server.
Example:
server1 ansible_host=192.168.1.6
server2 ansible_host=192.168.1.5
server3 ansible_host=192.168.1.7
server4 ansible_host=server_hostname
When running commands and playbooks, reference servers by their aliases instead of their IP addresses or hostnames. This simplifies targeting individual servers.
$ sudo ansible -i ansible/inventory -m ping server1
How to Configure Variable Names in Ansible Inventory File?
In Ansible, variables play an important role in managing differences between managed hosts. They allow for the representation of variations across systems when executing playbooks or ad hoc commands. For example, in the previous section, we utilized the ansible_host variable to specify the IP address of a managed node.
Within inventory files, variables can define various attributes such as hostnames, connection types, ports, and more. In the following example, we extend this concept by specifying the user used to establish remote connections to the nodes.
For each server entry, we define two variables: ansible_host, which specifies the IP of the host, and ansible_user, which specifies the user used for the remote connection.
server01 ansible_host=192.168.1.6 ansible_user=root
server02 ansible_host=192.168.1.5 ansible_user=user
Furthermore, variables can also be defined at the group level, allowing for streamlined management across multiple hosts. In this example, we create two separate variable groups - [webservers_a:vars] and [webservers_b:vars] - each specifying the user to connect to the managed nodes.
[webservers_a]
server01 ansible_host=192.168.1.6
[webservers_b]
server02 ansible_host=192.168.1.5
[webservers_a:vars]
ansible_user=root
[webservers_b:vars]
ansible_user=user
By configuring variables in this manner, you can efficiently manage host-specific attributes and streamline your Ansible operations across multiple hosts and groups.
Use Patterns to Target Commands Execution and Playbooks
When running commands and playbooks with Ansible, specifying a target is essential. Patterns offer a flexible way to target specific hosts, groups, or subgroups in your inventory file, supporting regular expressions and wildcards.
Consider the following inventory file:
[webservers]
192.168.1.6
192.168.1.5
[dbservers]
192.168.1.7
server_hostname
[development]
192.168.1.6
192.168.1.7
[production]
192.168.1.5
server_hostname
Now, suppose you need to execute a command targeting only the database servers running on production. You can use the following pattern:
$ ansible dbservers:\&production -m ping
Here, the & character denotes the logical operation AND, indicating that valid targets must be present in both groups. Since this is an ad hoc command in Bash, we include the \ escape character to avoid command-line errors.
Alternatively, to target only servers in the database group but not in production, you can use:
$ ansible dbservers:\!production -m ping
The “!” character signifies that a target must not be in a certain group. Again, we use the \ escape character to handle special characters in Bash.
For more advanced pattern options, such as positional patterns and regex, you can refer to the Ansible documentation.
Conclusion
This guide provided a comprehensive overview of Ansible inventories. We explored techniques for organizing nodes into groups and subgroups, configuring inventory variables, and leveraging patterns to target specific server groups when executing commands and playbooks.
If you are using a VPS Linux server, you can also use Ansible and configure inventory files.