DEV Community

Harsh Mishra
Harsh Mishra

Posted on

Ansible Inventory: Complete Guide for Beginner

Complete Guide to Ansible Inventory: From Beginner to Mastery

Ansible inventory is a key concept in automating infrastructure and configuration management. It defines the list of managed nodes (hosts) that Ansible interacts with during automation tasks. This guide will cover everything you need to know about Ansible Inventory, from basic concepts to advanced techniques, ensuring you can use inventories effectively in any Ansible deployment.


1. What is Ansible Inventory?

Ansible's inventory is a collection of managed nodes (hosts) that Ansible interacts with during automation tasks. These nodes can be grouped, and you can define variables specific to each host or group of hosts.

The inventory file can be written in various formats:

  • INI format (default)
  • YAML format
  • Dynamic inventory (e.g., cloud providers, external systems)

The inventory is the foundation of Ansible automation, providing the system with information on what hosts to manage and how to connect to them.


1.1 Inventory Basics: Formats, Hosts, and Groups

You can create your inventory file in one of many formats, depending on the inventory plugins you have. The most common formats are INI and YAML. A basic INI /etc/ansible/hosts might look like this:

INI Example:

mail.example.com

[webservers]
foo.example.com
bar.example.com

[dbservers]
one.example.com
two.example.com
three.example.com
Enter fullscreen mode Exit fullscreen mode

The headings in brackets ([]) are group names, which are used in classifying hosts and deciding what hosts you are controlling at what times and for what purposes. Group names should follow the same guidelines as creating valid variable names.

Here’s that same basic inventory file in YAML format:

YAML Example:

ungrouped:
  hosts:
    mail.example.com:
webservers:
  hosts:
    foo.example.com:
    bar.example.com:
dbservers:
  hosts:
    one.example.com:
    two.example.com:
    three.example.com:
Enter fullscreen mode Exit fullscreen mode

2. Structure of Ansible Inventory

Ansible allows you to manage your inventory in multiple formats, such as INI or YAML. The simplest way to define an inventory is in a file, typically called hosts or inventory.


2.1 Static Inventory (INI Format)

The default format is INI-like. Hosts are listed, and groups of hosts can be defined with [groupname] headers. You can also specify variables for each host or group of hosts.

INI Example:

# /etc/ansible/hosts

# Group of web servers
[web_servers]
web1.example.com
web2.example.com

# Group of database servers
[db_servers]
db1.example.com
db2.example.com

# Group of all servers
[all_servers:children]
web_servers
db_servers

# Variables specific to a group or host
[web_servers:vars]
http_port=80
max_clients=200

[db_servers:vars]
db_port=5432

# Host-specific variables
web1.example.com ansible_user=ubuntu ansible_ssh_private_key_file=/path/to/key
Enter fullscreen mode Exit fullscreen mode
  • Groups: [web_servers] and [db_servers] define groups of hosts. The children keyword is used to create nested groups.
  • Group Variables: Variables specific to a group are placed under the [groupname:vars] section.
  • Host Variables: Variables specific to a host can be defined on the same line as the hostname.

2.2 YAML Inventory Format

YAML is another popular format for writing Ansible inventories. It is more structured and human-readable.

YAML Example:

# /etc/ansible/hosts.yml

all:
  children:
    web_servers:
      hosts:
        web1.example.com:
          ansible_user: ubuntu
          ansible_ssh_private_key_file: /path/to/key
        web2.example.com:
          ansible_user: ubuntu
          ansible_ssh_private_key_file: /path/to/key
      vars:
        http_port: 80
        max_clients: 200
    db_servers:
      hosts:
        db1.example.com:
          ansible_user: ubuntu
        db2.example.com:
          ansible_user: ubuntu
      vars:
        db_port: 5432
Enter fullscreen mode Exit fullscreen mode
  • Groups and Hosts: The structure is similar to the INI format but uses indentation to represent groups and hosts.
  • Variables: Host-specific variables and group variables are defined inside the vars section.

2.3 Dynamic Inventory

A dynamic inventory is used when the inventory data comes from external sources such as cloud providers (AWS, Azure), virtual machines, or a database. Instead of a static file, a dynamic inventory uses a script or plugin to generate the list of hosts.

Example:

# Example command for AWS EC2 dynamic inventory

ansible-inventory -i ec2.py --list
Enter fullscreen mode Exit fullscreen mode

Ansible will use the ec2.py script to query the AWS EC2 API and return a list of available instances. Dynamic inventories are often used when dealing with cloud environments where hosts can be created or terminated frequently.


3. Inventory Grouping

Inventory groups allow you to categorize hosts in a logical manner. You can define groups based on any criteria (e.g., application role, environment, region).

3.1 Basic Grouping

INI Example:

[web_servers]
web1.example.com
web2.example.com

[db_servers]
db1.example.com
Enter fullscreen mode Exit fullscreen mode

Grouping Hosts: Hosts web1.example.com and web2.example.com are part of the web_servers group, while db1.example.com is part of the db_servers group.

YAML Example:

web_servers:
  hosts:
    web1.example.com:
    web2.example.com:
db_servers:
  hosts:
    db1.example.com:
Enter fullscreen mode Exit fullscreen mode

3.2 Group of Groups (Parent Groups)

You can create a parent group containing other groups (called children). This allows you to target multiple groups in one command.

INI Example:

[all_servers:children]
web_servers
db_servers
Enter fullscreen mode Exit fullscreen mode

Here, all_servers is a parent group that includes both web_servers and db_servers.

YAML Example:

all_servers:
  children:
    web_servers:
      hosts:
        web1.example.com:
        web2.example.com:
    db_servers:
      hosts:
        db1.example.com:
Enter fullscreen mode Exit fullscreen mode

3.3 Group Variables

You can assign variables to entire groups, which will then apply to all hosts within that group.

INI Example:

[web_servers:vars]
http_port=80
max_clients=200
Enter fullscreen mode Exit fullscreen mode

These variables will be applied to all hosts in the web_servers group.

YAML Example:

web_servers:
  hosts:
    web1.example.com:
    web2.example.com:
  vars:
    http_port: 80
    max_clients: 200
Enter fullscreen mode Exit fullscreen mode

3.4 Host-Specific Variables

You can also assign variables to individual hosts.

INI Example:

web1.example.com ansible_user=ubuntu
db1.example.com ansible_user=admin
Enter fullscreen mode Exit fullscreen mode

YAML Example:

web1.example.com:
  ansible_user: ubuntu
db1.example.com:
  ansible_user: admin
Enter fullscreen mode Exit fullscreen mode

3.5 Default Groups

Even if you don't define any groups in your inventory file, Ansible automatically creates two default groups: all and ungrouped.

  • all: This group contains every host in the inventory.
  • ungrouped: This group contains all hosts that don't belong to any other group besides all.

Every host will always belong to at least two groups: all and either ungrouped or some other group.

INI Example:

# /etc/ansible/hosts

mail.example.com

[webservers]
foo.example.com
bar.example.com

[dbservers]
one.example.com
two.example.com
three.example.com
Enter fullscreen mode Exit fullscreen mode

YAML Example:

ungrouped:
  hosts:
    mail.example.com:
webservers:
  hosts:
    foo.example.com:
    bar.example.com:
dbservers:
  hosts:
    one.example.com:
    two.example.com:
    three.example.com:
Enter fullscreen mode Exit fullscreen mode

3.6 Inventory Aliases

You can define aliases in your inventory, which are useful for giving a host a different name or setting specific variables.

INI Example:

jumper ansible_port=5555 ansible_host=192.0.2.50
Enter fullscreen mode Exit fullscreen mode

YAML Example:

jumper:
  ansible_port: 5555
  ansible_host: 192.0.2.50
Enter fullscreen mode Exit fullscreen mode

In this example, jumper is an alias for the host with IP 192.0.2.50 and the SSH port 5555. This can be helpful when working with systems that have non-standard hostnames or ports.


3.7 Inheriting Variable Values: Group Variables for Groups of Groups

You can apply variables to parent groups (also known as nested groups or groups of groups) as well as to their child groups. This allows you to inherit variables from a parent group.

INI Example:

[usa:children]
southeast
northeast
southwest
northwest

[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
Enter fullscreen mode Exit fullscreen mode

YAML Example:

usa:
  children:
    southeast:
      vars:
        some_server: foo.southeast.example.com
        halon_system_timeout: 30
    northeast:
    southwest:
    northwest:
Enter fullscreen mode Exit fullscreen mode

In this example, the southeast group is a child of the usa parent group, and it inherits the variables defined under [southeast:vars] in the INI format or under the vars section in the YAML format. The variables some_server and halon_system_timeout will be available to all hosts in the southeast group.


4. Variables in Inventory

Variables can be defined in several places in the inventory:

  • Group Variables: Define variables that apply to all hosts within a group.
  • Host Variables: Define variables for specific hosts.
  • Host-Specific Variables: Use the ansible_* prefix to define variables specific to each host.

4.1 Example with Group and Host Variables

INI Example:

[web_servers]
web1.example.com ansible_user=ubuntu
web2.example.com ansible_user=ubuntu

[db_servers]
db1.example.com ansible_user=admin
db2.example.com ansible_user=admin

[web_servers:vars]
http_port=80
max_clients=200

[db_servers:vars]
db_port=5432
Enter fullscreen mode Exit fullscreen mode

Variables like http_port and max_clients are applied to all hosts in the web_servers group, and db_port applies to all hosts in the db_servers group.

YAML Example:

web_servers:
  hosts:
    web1.example.com:
      ansible_user: ubuntu
    web2.example.com:
      ansible_user: ubuntu
  vars:
    http_port: 80
    max_clients: 200

db_servers:
  hosts:
    db1.example.com:
      ansible_user: admin
    db2.example.com:
      ansible_user: admin
  vars:
    db_port: 5432
Enter fullscreen mode Exit fullscreen mode

4.2 Host-Specific Variables

You can define host-specific variables like ansible_user directly on the host line.

INI Example:

web1.example.com ansible_user=ubuntu
Enter fullscreen mode Exit fullscreen mode

YAML Example:

web1.example.com:
  ansible_user: ubuntu
Enter fullscreen mode Exit fullscreen mode

4.3 Using Group and Host Variables in Playbooks

Variables defined in your inventory can be used in playbooks to customize tasks for your hosts. Here’s a simple example using two variables, http_port and max_clients, to configure a web server.

Example Inventory:

[web_servers:vars]
http_port=80
max_clients=200
Enter fullscreen mode Exit fullscreen mode

Example Playbook:

---
- name: Configure web server settings
  hosts: web_servers
  tasks:
    - name: Display the HTTP port
      debug:
        msg: "The HTTP port is set to {{ http_port }}"

    - name: Display the max clients
      debug:
        msg: "The max clients is set to {{ max_clients }}"
Enter fullscreen mode Exit fullscreen mode

In this example:

  • The http_port and max_clients variables are defined in the inventory.
  • The debug module is used to print these variables during the playbook run.

This demonstrates how you can use inventory variables in a simple, real-world scenario to customize settings for your servers.


4.4 Built-in Variables in Ansible

Here are some key built-in Ansible variables that are commonly used:

  • ansible_user: The user Ansible will use to connect to the host.
  • ansible_host: The IP address or hostname used for connecting to the host (if different from the inventory name).
  • ansible_ssh_private_key_file: The path to the private SSH key used for authentication.
  • ansible_connection: The connection type (e.g., ssh, local).
  • ansible_become: Whether to use privilege escalation (e.g., sudo).
  • ansible_hostname: The short hostname of the system.

5. Ansible Inventory Plugins

Ansible supports inventory plugins, which enable dynamic inventories for cloud providers and other systems. Popular inventory plugins include:

  • AWS EC2 Plugin: Automatically manage EC2 instances.
  • Azure RM Plugin: Manage Azure resources.
  • GCP Plugin: Manage Google Cloud resources.
  • VMware Plugin: For managing VMware environments.

INI Example:

# Configure the AWS EC2 plugin in ansible.cfg

[defaults]
inventory = ./ec2_inventory.py
Enter fullscreen mode Exit fullscreen mode

YAML Example:

# Configure the AWS EC2 plugin in ansible.cfg

defaults:
  inventory: ./ec2_inventory.py
Enter fullscreen mode Exit fullscreen mode

6. Advanced Inventory Techniques

6.1 Host Variables in Separate Files

You can store host variables in separate files using YAML. Ansible will automatically load variables from these files.

INI Example:

# /etc/ansible/hosts

[web_servers]
web1.example.com
web2.example.com
Enter fullscreen mode Exit fullscreen mode

YAML Example:

# /etc/ansible/group_vars/web_servers.yml
http_port: 80
max_clients: 200

# /etc/ansible/host_vars/web1.example.com.yml
ansible_user: ubuntu
Enter fullscreen mode Exit fullscreen mode

6.2 Using ansible_ssh_private_key_file for Key Authentication

If you're using SSH key authentication, you can specify the private key for each host in the inventory.

INI Example:

web1.example.com ansible_ssh_private_key_file=/path/to/key
Enter fullscreen mode Exit fullscreen mode

YAML Example:

web1.example.com:
  ansible_ssh_private_key_file: /path/to/key
Enter fullscreen mode Exit fullscreen mode

7. How to Use the Inventory in Commands

When running commands like ansible, ansible-playbook, or ansible-inventory, you can specify the inventory file using the -i option.

INI Example:

ansible -i /etc/ansible/hosts web_servers -m ping
Enter fullscreen mode Exit fullscreen mode

YAML Example:

ansible -i /etc/ansible/hosts.yml web_servers -m ping
Enter fullscreen mode Exit fullscreen mode

8. Best Practices for Inventory Management

  • Use Grouping Wisely: Organize your hosts logically (e.g., by environment, role, or region).
  • Centralize Inventory: Keep a central location for the inventory file, such as /etc/ansible/hosts or a shared network location.
  • Use Variables Effectively: Avoid hardcoding variables. Use group and host-specific variables to keep configurations modular.
  • Version Control: Store your inventory files in version control (e.g., Git) to keep track of changes.

9. Conclusion

Ansible’s inventory system is a powerful feature that allows you to manage and organize the hosts you want to automate. Understanding how to work with static inventories (INI/YAML), dynamic inventories, and inventory variables will greatly enhance your ability to manage complex infrastructures. By mastering inventory management, you’ll be able to target specific hosts, organize groups of servers, and streamline your Ansible automation workflows.

Top comments (0)