<- Back to BlogDevOps

Ansible Inventory Files Explained: INI, YAML, Groups, and Variables (2026)

Need an inventory file without hand-editing groups?

Use the Ansible Inventory Generator to create INI or YAML structure, then validate connectivity and variables with Ansible itself before a playbook run.

An Ansible inventory answers a practical question: which machines belong to which groups, and how should Ansible connect to them? It is not merely a list of IP addresses. Inventory structure controls targeting, group inheritance, connection variables, and the names a playbook can use. A readable inventory reduces the risk of deploying to the wrong environment.

1. What an inventory describes

An inventory contains hosts and groups. A host can be named by DNS name, IP address, or an alias with connection variables. Groups let a play target a role such as web, database, staging, or production. Child groups create larger logical sets, while host and group variables supply connection or application settings.

Inventory conceptExample purpose
HostOne machine or connection alias
GroupTarget all web servers
Child groupCombine web and worker groups
Host variableOverride a port or interpreter
Group variableSet shared environment values

Group names are labels used by playbooks. Use stable names that describe responsibility and environment, not temporary machine names. Avoid ambiguous labels such as new or server1 once the inventory becomes shared.

2. INI inventory syntax

[web]
+web-1 ansible_host=203.0.113.10
+web-2 ansible_host=203.0.113.11
+
+[db]
+db-1 ansible_host=203.0.113.20
+
+[production:children]
+web
+db

INI is compact and easy to scan for simple host lists. Key-value pairs after a host define host variables. Group relationships use special sections such as :children, and group variables use :vars. Keep complex nested data out of inline host declarations when it becomes difficult to review.

3. YAML inventory syntax

all:
  children:
    web:
      hosts:
        web-1:
          ansible_host: 203.0.113.10
    production:
      children:
        web:

YAML expresses nesting explicitly and is often easier to extend with group variables and structured data. It is also sensitive to indentation, duplicate keys, and scalar types. A value such as an unquoted number may be parsed differently from a string that a module expects, so validate the result with Ansible.

4. Variables and precedence

Ansible has several variable sources, including inventory host variables, group variables, play variables, role defaults, and extra variables. When the same name appears in several places, precedence decides the winner. Avoid creating a maze of overrides. Put connection facts near inventory, role configuration near the role, and secrets in a vault or external secret manager.

Connection variables are common: ansible_user, ansible_port, ansible_ssh_private_key_file, and ansible_python_interpreter. A private key path is not the private key itself, but it still reveals a local filesystem assumption. Do not put private key contents or passwords in a public inventory.

Use group variables for shared non-secret settings. For credentials, use Ansible Vault or an approved secret backend. An inventory generator can create the shape, but it cannot decide which access policy is appropriate for a production fleet.

5. A safe workflow

  1. Create separate inventories for development, staging, and production, or use clearly isolated groups.
  2. Generate a first draft with the Ansible Inventory Generator.
  3. Inspect every host and connection variable before saving.
  4. Run ansible-inventory -i inventory.yml --graph to inspect group membership.
  5. Run ansible-inventory -i inventory.yml --host web-1 to inspect resolved host data.
  6. Test with a read-only play or ansible all -m ping before a change playbook.
  7. Keep secrets outside the inventory and review changes like code.

For SSH details, pair the inventory with the SSH Config Generator. For service configuration, keep generated systemd or Nginx files separate from inventory so each tool has one clear responsibility.

6. Common inventory errors

  • Wrong file format: Ansible may parse an INI-like file differently from YAML.
  • Targeting the wrong group: a play pattern can match more hosts than expected.
  • Duplicate YAML keys: the last value may win silently depending on the parser.
  • Bad indentation: a host becomes a sibling of a group rather than a child.
  • Connection mismatch: DNS, SSH user, port, key, and Python interpreter must all agree.
  • Secret in source control: rotate exposed credentials and move them to a protected store.

Before production, print the graph, verify the selected group, and run a harmless command against one known host. A successful parser run proves syntax, not that the target is the machine you intended.

Conclusion

Ansible inventory is an executable map of infrastructure. Use stable groups, explicit environments, deliberate variable placement, and validation commands before changes. Generate boilerplate locally, but let Ansible and a human review determine whether the inventory is safe to run.

Frequently Asked Questions

What is an Ansible inventory?
It describes hosts, groups, relationships, and variables that Ansible uses to target machines.
Should I use INI or YAML?
INI is compact for simple lists; YAML is easier to extend with nested groups and structured variables.
Where should secrets go?
Use Ansible Vault or an approved secret backend rather than putting passwords or private key contents in inventory.
How do I inspect group membership?
Run ansible-inventory with the --graph option against the exact inventory file.
Can a generator validate connectivity?
No. It can create structure; Ansible must validate parsing, connection, and permissions.
How do I avoid deploying to the wrong environment?
Separate environments, use explicit group names, print the graph, and test a known host with a read-only command first.