Ansible Inventory
Introduction
An Ansible inventory is a file or set of files that defines the hosts and groups that Ansible will manage. It's one of the fundamental components of Ansible that allows you to specify which servers you want to control and how to organize them logically. Think of it as your address book for all the machines you want to automate.
In this guide, we'll learn:
- What an Ansible inventory is
- How to create and structure inventory files
- How to define host patterns and groups
- How to assign variables to hosts and groups
- How to use dynamic inventories
Basic Inventory File
At its simplest, an inventory is a text file that lists server names or IP addresses. By default, Ansible looks for this file at /etc/ansible/hosts
, but you can specify a different location using the -i
flag when running Ansible commands.
Simple Inventory Example
Let's start with a basic inventory file:
# Simple inventory example
web1.example.com
web2.example.com
db1.example.com
192.168.1.100
This inventory contains four hosts: three identified by their domain names and one by its IP address. With this inventory file, you can already start running Ansible commands against these hosts.
Using the Inventory
To use this inventory, you can run a simple ping command:
ansible all -i inventory -m ping
Output:
web1.example.com | SUCCESS => {
"changed": false,
"ping": "pong"
}
web2.example.com | SUCCESS => {
"changed": false,
"ping": "pong"
}
db1.example.com | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.1.100 | SUCCESS => {
"changed": false,
"ping": "pong"
}
Grouping Hosts
A more powerful approach is to organize your hosts into groups. This allows you to apply configurations or run playbooks against specific sets of machines.
Group Example
# Group example
[webservers]
web1.example.com
web2.example.com
[databases]
db1.example.com
[development]
192.168.1.100
In this example, we've created three groups:
webservers
containing two web serversdatabases
containing one database serverdevelopment
containing one server identified by IP
Nested Groups
You can also create groups of groups, called nested groups:
# Nested groups example
[webservers]
web1.example.com
web2.example.com
[databases]
db1.example.com
[development]
dev.example.com
[production:children]
webservers
databases
Here, we've created a group called production
that includes all hosts in both the webservers
and databases
groups.
Inventory Patterns
When running Ansible, you can specify patterns to target specific hosts or groups:
# Run on all webservers
ansible webservers -i inventory -m ping
# Run on all hosts in production
ansible production -i inventory -m ping
# Run on all hosts
ansible all -i inventory -m ping
# Run on a specific host
ansible web1.example.com -i inventory -m ping
# Run on multiple groups
ansible webservers:databases -i inventory -m ping
# Run on all hosts except databases
ansible all:!databases -i inventory -m ping
# Run on hosts that are in both webservers and production
ansible webservers:&production -i inventory -m ping
Host and Group Variables
You can assign variables to hosts or groups in your inventory file. These variables can then be used in your playbooks and templates.
Host Variables
# Host variables example
[webservers]
web1.example.com http_port=80 max_connections=100
web2.example.com http_port=8080 max_connections=200
[databases]
db1.example.com db_port=5432 backup_time=midnight
Group Variables
# Group variables example
[webservers]
web1.example.com
web2.example.com
[webservers:vars]
http_port=80
ansible_user=apache
max_connections=100
[databases]
db1.example.com
[databases:vars]
db_port=5432
ansible_user=postgres
backup_time=midnight
Separate Variable Files
For larger projects, it's better to keep variables in separate files. Ansible looks for these variables in the host_vars
and group_vars
directories:
inventory/
├── hosts
├── group_vars/
│ ├── webservers.yml
│ └── databases.yml
└── host_vars/
├── web1.example.com.yml
└── db1.example.com.yml
Example content of group_vars/webservers.yml
:
---
http_port: 80
ansible_user: apache
max_connections: 100
Connection Variables
You can specify connection details in your inventory:
# Connection variables example
[webservers]
web1.example.com ansible_host=192.168.1.101 ansible_user=admin ansible_port=2222
web2.example.com ansible_connection=ssh ansible_ssh_private_key_file=/path/to/key.pem
[monitoring]
monitor.example.com ansible_connection=winrm ansible_user=admin ansible_password=secret
Common connection variables include:
ansible_host
: The actual hostname or IP to connect to (if different from the inventory name)ansible_port
: The port to connect toansible_user
: The username to use for the connectionansible_connection
: The connection type (ssh, winrm, local)ansible_ssh_private_key_file
: Path to the SSH private key fileansible_password
: The password for the connection (consider using Ansible Vault instead)
Inventory File Formats
Ansible supports several formats for inventory files:
INI Format (Traditional)
[webservers]
web1.example.com
web2.example.com
YAML Format
all:
children:
webservers:
hosts:
web1.example.com:
web2.example.com:
http_port: 8080
databases:
hosts:
db1.example.com:
db2.example.com:
Dynamic Inventory
For dynamic environments (like cloud infrastructure), Ansible supports dynamic inventory scripts. These scripts generate inventory information on the fly.
Using Dynamic Inventory
A dynamic inventory is usually a script (Python, Shell, etc.) that outputs JSON in a specific format:
ansible-playbook -i inventory_script.py playbook.yml
Here's a simplified diagram of how dynamic inventory works:
Practical Example: Multi-Environment Setup
Let's create a more comprehensive example for a real-world application with development, staging, and production environments:
# File: inventory/hosts
# Web Servers
[web]
web-prod-01.example.com
web-prod-02.example.com
web-staging-01.example.com
web-dev-01.example.com
# Database Servers
[db]
db-prod-01.example.com
db-staging-01.example.com
db-dev-01.example.com
# Environment-based groups
[production]
web-prod-01.example.com
web-prod-02.example.com
db-prod-01.example.com
[staging]
web-staging-01.example.com
db-staging-01.example.com
[development]
web-dev-01.example.com
db-dev-01.example.com
# Application-based groups
[app:children]
web
db
# Default connection settings
[all:vars]
ansible_user=deploy
ansible_connection=ssh
With this setup, you can:
- Target all web servers with
ansible web -i inventory/hosts -m ping
- Target production environment with
ansible production -i inventory/hosts -m ping
- Target staging web servers with
ansible web:&staging -i inventory/hosts -m ping
Using the Inventory in a Playbook
Here's how to use your inventory in a playbook:
---
# deploy_webserver.yml
- name: Configure webservers
hosts: webservers
become: yes
tasks:
- name: Install nginx
apt:
name: nginx
state: present
- name: Start nginx service
service:
name: nginx
state: started
enabled: yes
- name: Deploy configuration
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
vars:
http_port: "{{ http_port | default('80') }}"
Run the playbook with:
ansible-playbook -i inventory deploy_webserver.yml
Best Practices
- Keep It Organized: Group related hosts together and use meaningful group names.
- Use Version Control: Keep your inventory files in version control.
- Separate Variables: Use group_vars and host_vars directories for variables.
- Use Patterns Carefully: Be precise with patterns to avoid unintended changes.
- Consider Dynamic Inventory: For cloud environments, dynamic inventory is usually better.
- Limit Access Variables: For sensitive data, use Ansible Vault.
- Document Your Inventory: Add comments to explain the purpose of groups and special variables.
Summary
The Ansible inventory is a fundamental component that defines what hosts Ansible manages and how they're organized. We've covered:
- Basic inventory structure and syntax
- Host and group organization
- Variable assignment at host and group levels
- Connection parameters
- Different inventory formats
- Dynamic inventories for cloud environments
- Practical examples and patterns
With a well-structured inventory, you can organize your infrastructure logically and target specific parts of it for configuration and deployment tasks.
Exercise: Create Your First Inventory
- Create an inventory file for a small infrastructure with two web servers and one database server.
- Add appropriate groups and variables.
- Run a simple Ansible command against each group to verify your inventory works.
- Create a simple playbook that uses host and group variables from your inventory.
Additional Resources
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)