Skip to main content
Cloud DevOps Solutions
Get a quote Talk to an engineer

Ansible / Config Mgmt

Ansible Inventory Design: Static, Dynamic and Smart

Ansible inventory is the list of hosts and groups your playbooks target. We design it as static YAML where hosts rarely change, as dynamic inventory plugins that read AWS or Azure where they do, and as AWX smart inventories that filter across sources, so targeting stays accurate.

Key takeaways

  • A wrong inventory is more dangerous than a wrong playbook, because it decides where changes land.
  • Cloud hosts belong in dynamic inventory driven by tags, not in hand-edited files.
  • Groups express roles and environments; variables attach to groups, not individual hosts.
  • Smart inventories in AWX let you target hosts by fact or name across several sources.
  • Inventory should be validated in CI like any other code.

Inventory decides where your changes land

Teams spend most of their review energy on playbooks and almost none on inventory. That is backwards. A perfect playbook run against the wrong group is still an incident. We have seen stale host files that include decommissioned servers (causing timeouts and noisy failures), and ones that miss new autoscaled instances (leaving them unpatched and unhardened for months).

Inventory is where Ansible meets reality. This page explains how we design it as part of our Ansible configuration management service, and when to pick static files, cloud plugins or AWX smart inventories.

What good looks like

  • Every managed host appears in the inventory without anyone typing it in, or the inventory is small enough that typing it is genuinely fine.
  • Groups map to how you operate: environment (production, staging), role (web, db), and sometimes region.
  • A host can be in several groups. Variables come from groups, so changing a setting for all web servers is one line.
  • A reviewer can run one command and see which hosts a playbook will touch before it runs.
  • Credentials for reading the cloud API are read-only and scoped narrowly.

How it works in practice

Static inventory

For a small, stable fleet, a YAML file is clear and reviewable:

all:
  children:
    production:
      children:
        web:
          hosts:
            web01.example.internal:
            web02.example.internal:
        db:
          hosts:
            db01.example.internal:
    staging:
      children:
        web:
          hosts:
            web-stg01.example.internal:

Variables go in group_vars/web.yml, group_vars/production.yml and so on. When the same host belongs to web and production, Ansible merges both sets of variables according to documented precedence, which we write down for your team.

Dynamic inventory on AWS

For autoscaling groups and short-lived instances, a static file is wrong by definition. The amazon.aws.aws_ec2 plugin reads instance data directly:

# inventories/aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
  - eu-west-1
filters:
  instance-state-name: running
  tag:ManagedBy: ansible
keyed_groups:
  - key: tags.Environment
    prefix: env
  - key: tags.Role
    prefix: role
hostnames:
  - tag:Name
  - private-ip-address
compose:
  ansible_host: private_ip_address

This creates groups such as env_production and role_web from tags. The quality of the inventory is therefore the quality of your tagging, which is why we agree a tag standard with whoever runs your cloud accounts. If you also use Terraform, add the tags in code so every instance is born correctly labelled, as described in our Terraform service.

You can preview what the plugin returns without running anything:

ansible-inventory -i inventories/aws_ec2.yml --graph
ansible-inventory -i inventories/aws_ec2.yml --host web01 --yaml

Dynamic inventory on Azure

Azure uses the azure.azcollection.azure_rm plugin, with a file ending in azure_rm.yml. The ideas are the same: filter by resource group or tag, create groups with keyed_groups, and compose a reachable ansible_host. Authentication uses a service principal or managed identity, scoped to reader access.

Combining sources

Pointing Ansible at a directory merges everything inside it. A common layout is one dynamic file for cloud, one static file for on-premises hosts and a shared group_vars directory. The rule is simple: group names must mean the same thing in every source.

AWX inventories and smart inventories

In AWX or Automation Platform, inventories are objects with sources that sync on a schedule. A smart inventory is a filtered view across them. Useful examples include all hosts with a given operating system, all hosts in env_production with a fact showing a pending reboot, or all hosts whose name matches a pattern. Smart inventories rely on facts being cached, so we enable fact caching and a scheduled fact-gathering job. They pair naturally with patching automation.

Decisions and trade-offs

Static versus dynamic. Static is easy to read and review, and it works offline. Dynamic is always current but depends on API access and tags. For mixed estates we use both, and we keep the static part small.

Tags versus naming conventions. Tags are more reliable than parsing hostnames. Where a legacy estate has no tags, we begin with naming patterns and migrate to tags gradually.

Variables on hosts. Tempting, and a source of surprises. If one server needs a special setting, that is often a sign it deserves its own group.

When a CMDB is better. If you already have a trusted CMDB, we can write a small inventory script or plugin against it instead of duplicating data. If your CMDB is not trusted, do not build on it.

Common failure modes

  • Untagged instances. They silently drop out of every group. We add a CI or scheduled check that lists untagged hosts.
  • Name collisions across accounts. Two accounts with a host called web01. We use a hostname scheme that includes environment or account.
  • API rate limits and slow runs. Large estates make inventory refresh slow. We enable caching on the plugin and scope regions and filters tightly.
  • Over-broad credentials. Inventory needs read access only. Anything more is a risk. See secrets handling for how credentials are stored.
  • Ambiguous precedence. Variables defined in several places. We document the order and keep the places few.

Delivery and handover

You receive the inventory files and plugin configs in Git, a tag standard, CI that runs ansible-inventory --list and fails on duplicate hosts or missing groups, and AWX inventory sources if you use AWX. Our documentation deliverable includes a variable reference that shows which group each setting comes from.

A handover detail that saves a weekend

We leave a short “inventory contract” in the repository: which group names are stable and safe to target, which are generated and may change, and which variables each group is allowed to set. Without it, a new engineer invents a group during an incident and the next sync quietly removes it. Keep the contract next to the inventory, review it when cloud tagging conventions change, and treat a renamed tag as a breaking change.

How to tell it is working

  • New instances appear in the right groups within one sync interval, with no human involved.
  • Retired instances disappear from runs without edits.
  • You can answer “which hosts will this change touch?” before pressing run.
  • Host-level variable overrides are rare and each has a comment.
  • Nobody maintains a spreadsheet of servers on the side.

If you are not sure your inventory matches your estate, contact us and we will compare the two.

References

How we deliver it

  1. 01

    Map your estate

    We list environments, accounts, regions, on-premises hosts and how servers are currently identified and tagged.

  2. 02

    Choose the sources

    Static files for stable hosts, cloud plugins for elastic ones, and a decision on how the two coexist.

  3. 03

    Design groups and variables

    Groups for environment, role and region, with a clear variable precedence plan and minimal host-level overrides.

  4. 04

    Implement plugins and tagging

    Inventory plugins are configured with filters, keyed groups and compose rules, and tag standards are agreed with your cloud owners.

  5. 05

    Validate in CI

    Pipelines run ansible-inventory to confirm that groups resolve, hosts are reachable by name and variables are what you expect.

  6. 06

    Load into AWX

    Sources are synced on a schedule, and smart inventories are defined for patching, compliance and ad hoc work.

Tools and technologies

Ansibleansible-inventoryamazon.aws.aws_ec2azure.azcollection.azure_rmAWXAnsible Automation PlatformTerraformAWS Systems ManagerJinja2yamllint

Frequently asked questions

What is the difference between static and dynamic inventory in Ansible?
Static inventory is a file you maintain by hand, listing hosts and groups. Dynamic inventory is generated at run time by a plugin that queries a source such as AWS, Azure or a CMDB. Dynamic suits elastic cloud fleets, while static suits small, stable environments and lab setups.
How does AWS dynamic inventory work with Ansible?
The amazon.aws.aws_ec2 plugin queries the EC2 API using your credentials, then builds groups from tags, instance types, regions or any attribute you specify. You describe filters and keyed groups in a YAML file ending in aws_ec2.yml, and Ansible produces the host list on each run.
What is an AWX smart inventory?
A smart inventory is a virtual inventory in AWX that selects hosts from other inventories using a filter, such as hosts whose facts show a particular operating system. It does not store hosts itself. It is useful for cross-cutting jobs like patching all Ubuntu hosts across several environments.
Can one inventory cover both cloud and on-premises servers?
Yes. Ansible merges multiple inventory sources, so you can combine a dynamic AWS source with a static file for data centre hosts. We make group names consistent across sources so a playbook targeting the web group works everywhere, regardless of where the host runs.
Where should variables live in an inventory?
Mostly in group_vars, attached to groups for environment and role. Host_vars should be rare and commented. Putting variables on groups keeps them reviewable and predictable, and it makes precedence far easier to reason about when something behaves differently on one server.

Talk to an engineer about ansible inventory management

Book a free 30-minute call. We review your current setup and tell you honestly whether and how we can help.

Written by Saddique Khan, DevOps / SRE / Cloud Consultant Engineer. Last updated 2026-10-08.