G
GuideDevOps
Lesson 3 of 14

Inventory Files

Part of the Ansible tutorial series.

What is an Inventory?

Ansible needs to know what it is automating. By default, Ansible has no idea what servers you own.

An Inventory is simply a file containing a list of your servers (IP addresses or DNS names). It allows you to organize your servers into logical groups so you can target specific subsets of your infrastructure.

By default, Ansible looks for an inventory file at /etc/ansible/hosts, but it is best practice to keep your inventory file in the same directory as your project code.


Static Inventory Formats

Ansible supports two main formats for static inventories: INI and YAML.

1. The INI Format

This is the traditional, most commonly used format for simpler projects. It relies on brackets [ ] to define groups.

# A server not assigned to any specific group
192.168.1.10
 
# A group named "webservers"
[webservers]
web1.example.com
web2.example.com
10.0.0.50
 
# A group named "databases"
[databases]
db-primary.example.com
db-replica.example.com

2. The YAML Format

The YAML format is more modern and makes it easier to pass complex variables to your servers directly within the inventory.

all:
  hosts:
    192.168.1.10:
  children:
    webservers:
      hosts:
        web1.example.com:
        web2.example.com:
        10.0.0.50:
    databases:
      hosts:
        db-primary.example.com:
        db-replica.example.com:

Groups of Groups (Children)

Sometimes, you want to perform an action on all servers in a specific region, regardless of whether they are web servers or databases. You can establish group hierarchies using the :children suffix in INI format.

[web_eu]
eu-web-1.example.com
eu-web-2.example.com
 
[db_eu]
eu-db-1.example.com
 
# Create a master "europe" group that includes the groups above
[europe:children]
web_eu
db_eu

When you target the europe group, Ansible will execute against all three servers.


Inventory Variables

You can assign variables directly to hosts or groups in the inventory file. This is incredibly useful for setting SSH users, custom SSH ports, or application-specific flags.

Host Variables

Assigning a custom SSH port and user to a specific machine:

[webservers]
web1.example.com ansible_port=2222 ansible_user=admin
web2.example.com ansible_user=ubuntu

Group Variables

Assigning variables to an entire group using the :vars suffix:

[databases]
db-1.example.com
db-2.example.com
 
[databases:vars]
ansible_user=postgres
database_version=14.1

Common Built-in Ansible Variables

VariableWhat it does
ansible_userThe SSH username to connect with (default is your current local user).
ansible_portThe SSH port to connect to (default is 22).
ansible_ssh_private_key_fileThe path to the private .pem or .id_rsa key for authentication.
ansible_becomeBoolean (true/false). Tells Ansible to use sudo.
ansible_become_passwordThe sudo password (if required). Warning: Don't put plain text passwords in Git! Use Ansible Vault.
ansible_python_interpreterThe path to Python on the target host (e.g., /usr/bin/python3).

Verifying Your Inventory

Before running a massive automation script, you should verify that Ansible is reading your inventory file correctly.

If your inventory file is named inventory.ini, you can list all the hosts Ansible found using the --list-hosts flag:

# List all hosts in the inventory
ansible all -i inventory.ini --list-hosts
 
# List only the databases
ansible databases -i inventory.ini --list-hosts

Dynamic Inventories (Cloud Environments)

Static INI files are great if you manage your own physical servers. But what if you are using AWS, where servers scale up and down automatically every hour? You can't manually update an INI file every time an EC2 instance launches.

Dynamic Inventories solve this by replacing the static text file with a plugin or script that queries your cloud provider's API in real-time.

For example, using the aws_ec2 plugin, you can tell Ansible: "Target all EC2 instances currently running in us-east-1 that have the tag Role: Webserver."

# aws_ec2.yaml (Dynamic Inventory config)
plugin: aws_ec2
regions:
  - us-east-1
keyed_groups:
  - key: tags.Role
    prefix: role_

Ansible will dynamically create a group called role_Webserver on the fly based on AWS tags!