Elevating IaC Workflows with Spacelift Stacks and Dependencies 🛠️

Register for the July 23 demo →


Working with Ansible Inventory – Basics and Use Cases

Working with Ansible Inventory

Spacelift and Ansible

Manage and orchestrate Ansible with Spacelift’s vibrant ecosystem and excellent GitOps flow. Create powerful custom workflows combining multiple IaC tools.

Book a demo

In this blog post, we will dive deep into different concepts around building an Ansible inventory, along with best practices. We will look into basic functionality, managing variables, and combining multiple inventory sources and options for working with dynamic inventories. 

If you are new to Ansible or interested in other Ansible concepts, these Ansible tutorials on Spacelift’s blog might be handy.

Ansible Inventory Basics

An Ansible inventory is a collection of managed hosts we want to manage with Ansible for various automation and configuration management tasks. Typically, when starting with Ansible, we define a static list of hosts known as the inventory. These hosts can be grouped into different categories, and then we can leverage various patterns to run our playbooks selectively against a subset of hosts. 

By default, the inventory is stored in /etc/ansible/hosts, but you can specify a different location with the -i flag or the ansible.cfg configuration file. 

Let’s take a look at what a simple inventory looks like. The most common formats are either INI or YAML. 



In this example, we use the INI format, define four managed hosts, and we group them into two host groups; webservers and databases. The group names can be specified between brackets, as shown above.

Inventory groups are one of the handiest ways to control Ansible execution. Hosts can also be part of multiple groups.





Note: By default, we can also reference two groups without defining them. The all group targets all our hosts in the inventory, and the ungrouped contains any host that isn’t part of any user-defined group.

We can also create nested groups of hosts if necessary.




To list a range of hosts with similar patterns, you can leverage the range functionality instead of defining them one by one. For example, to define ten hosts (host01, host02, …. host10):


Another useful functionality is the option to define aliases for hosts in the inventory. For example, we can run Ansible against the host alias host01 if we define it in the inventory as:

host01 ansible_host=host01.mycompany.com

A typical pattern for inventory setups is separating inventory files per environment. Find below an example of keeping separate staging and production inventories.





When defining groups of hosts in the inventory, we categorize them based on application, function, location, department, and other shared characteristics between hosts, allowing us to target them in groups. Try understanding which groups make sense for your use case and automation needs.

Inventory and Variables

An important aspect of Ansible’s project setup is variable’s assignment and management. Ansible offers many different ways of setting variables (check this blog post for detailed information about Ansible variables), and defining them in the inventory is one of them. 

For example, let’s define one variable for a different application version for every host in our dummy inventory from before.

host01.mycompany.com app_version=1.0.1
host02.mycompany.com app_version=1.0.2

host03.mycompany.com app_version=1.0.3
host04.mycompany.com app_version=1.0.4

Ansible-specific connection variables such as ansible_user or ansible_host are examples of host variables defined in the inventory. Check the Connecting to hosts: behavioral inventory parameters section of the docs for more options.

Similarly, variables can also be set at the group level in the inventory and offer a convenient way to apply variables to hosts with common characteristics.





Although setting variables in the inventory is possible, it’s usually not the preferred way. Instead, store separate host and group variable files to enable better organization and clarity for your Ansible projects. Note that host and group variable files must use the YAML syntax. 

In the same directory where we keep our inventory file, we can create two folders named group_vars and host_vars containing our variable files. For example, we could have a file group_vars/webservers that contains all the variables for web servers:


http_post: 80
ansible_user: automation_user

A possible use case for having separate variable files instead of storing them in the inventory is to keep sensitive values without persisting them in playbooks or source control systems. 

As mentioned, there are multiple options to set variables in Ansible, so look at the official documentation Understanding variable precedence and How variables are merged if you plan on using different layers for your vars. 

Multiple Ansible Inventory Sources

We have the option to combine different inventories and sources, such as directories, dynamic inventory scripts, or inventory plugins during runtime or in the configuration. 

This becomes especially useful in cases where we want to target multiple environments or otherwise isolated setups. For example, to target the development, testing, staging, and production hosts all at the same time:

ansible-playbook apply_updates.yml -i development -i testing -i staging -i production

We can combine multiple inventory sources in a directory and then manage them as one. This approach comes in handy when controlling static and dynamic hosts.


Then, we can run playbooks against all hosts in these inventories like this:

ansible-playbook apply_updates.yml -i inventory

Ansible Dynamic Inventories

Many modern environments are dynamic, cloud-based, possibly spread across multiple providers, and constantly changing. In these cases, maintaining a static list of managed nodes is time-consuming, manual, and error-prone. 

Ansible has two methods to properly track and target a dynamic set of hosts: inventory plugins and inventory scripts. The official suggestion is to prefer inventory plugins that benefit from the recent updates to ansible core. 

To see a list of available inventory plugins you can leverage to build dynamic inventories, you can execute ansible-doc -t inventory -l. We will look at one of them, the amazon.aws.aws_ec2, to get hosts from Amazon Web Services EC2. 

For plugin-specific docs and examples, use the command ansible-doc -t inventory amazon.aws.aws_ec2. Install the Ansible Galaxy collection amazon.aws to work with the plugin by running ansible-galaxy collection install amazon.aws

For this example, we have created four ec2 instances on AWS, and we would like to build an inventory file dynamically using the plugin. 

Ansible inventory AWS instance

We added two tags, environment and role, on these ec2 instances that we will later use to create inventory groups. 

Let’s create a YAML file named dynamic_inventory_aws_ec2.yml with the plugin configuration required for our use case.


plugin: amazon.aws.aws_ec2
  - us-east-1
  - us-east-2
  - us-west-2
hostnames: tag:Name
  - key: placement.region
    prefix: aws_region
  - key: tags['environment']
    prefix: env
  - key: tags['role']
    prefix: role
   # add hosts to the "private_only" group if the host doesn't have a public IP associated to it
  private_only: "public_ip_address is not defined"
  # use a private address where a public one isn't assigned
  ansible_host: public_ip_address|default(private_ip_address)

We declare the plugin we want to use and other options, including regions to consider fetching data from, setting hostnames from the tag Name, and creating inventory groups based on region, environment, and role. 

Let’s view the generated inventory with the command:

ansible-inventory -i dynamic_inventory_aws_ec2.yml --graph
Dynamic Inventory AWS EC2

The plugin fetches information from our AWS account and creates several groups according to our configuration and options. 

To persist the inventory to a file, you can use this command:

ansible-inventory -i dynamic_inventory_aws_ec2.yml --list --output inventory/dynamic_inventory_aws_ec2 -y

In case you want to integrate a source that isn’t covered by the existing inventory plugins, you also have the option to develop your own custom inventory plugin.

How Spacelift Can Help You With Ansible Projects

Spacelift’s vibrant ecosystem and excellent GitOps flow can greatly assist you in managing and orchestrating Ansible. By introducing Spacelift on top of Ansible, you can then easily create custom workflows based on pull requests and apply any necessary compliance checks for your organization. Another great advantage of using Spacelift is that you can manage different infrastructure tools like Ansible, Terraform, Pulumi, AWS CloudFormation, and even Kubernetes from the same place and combine their Stacks with building workflows across tools.

If you want to learn more about Spacelift working with Ansible, check our documentation, read our Ansible guide or book a demo with one of our engineers.

Key Points

In this article, we explored Ansible inventory basics and various use cases for defining groups and variables in static inventories. We also learned how to combine multiple inventory sources and an example of fetching our inventory of hosts dynamically from AWS. 

Thank you for reading, and I hope you enjoyed this as much as I did.

Manage Ansible Better with Spacelift

Spacelift helps you manage the complexities and compliance challenges of using Ansible. It brings with it a GitOps flow, so your infrastructure repository is synced with your Ansible Stacks, and pull requests show you a preview of what they’re planning to change. It also has an extensive selection of policies, which lets you automate compliance checks and build complex multi-stack workflows.

Learn More

The Practitioner’s Guide to Scaling Infrastructure as Code

Transform your IaC management to scale

securely, efficiently, and productively

into the future.

ebook global banner
Share your data and download the guide