Ansible Inventory Generator
Generate a static Ansible INI inventory from host rows, group variables, and parent groups with review warnings before playbook use.- {{ error }}
- {{ warning }}
{{ result.inventoryText || '# Fix validation errors to generate inventory.ini.' }}
| Alias | ansible_host | Groups | Host variables | Source line | Copy |
|---|---|---|---|---|---|
|
No valid hosts parsed
Fix host row errors or load a sample before exporting the host ledger.
|
|||||
| {{ host.alias }} | {{ host.ansibleHost || host.alias }} | {{ host.groups.join(', ') || '-' }} | {{ host.hostVarText || '-' }} | {{ host.lineNumber }} | |
| Severity | Check | Detail | Recommendation | Copy |
|---|---|---|---|---|
| {{ row.severity }} | {{ row.check }} | {{ row.detail }} | {{ row.recommendation }} |
Introduction:
Before a playbook can change a server, router, switch, or virtual machine, Ansible needs a dependable inventory. The inventory is the control node's plain-text map of managed hosts: the names Ansible will target, the groups those names belong to, and the connection variables that tell Ansible how to reach them. A messy inventory can make a play run against the wrong group, hide duplicate aliases, or depend on a hostname that resolves only for one operator.
Static inventory files still have a place beside dynamic cloud discovery. They are easy to review in a change request, do not require provider credentials, and make a bounded rollout set visible before automation runs. INI inventory is compact enough for small batches, labs, jump-start network inventories, and temporary change windows, as long as the operator remembers that a clean text file is not the same thing as a tested connection.
- Inventory alias
- The unique host name Ansible uses inside the inventory and play output.
- Connection address
- The host name or IP address used for the actual connection when it differs from the alias, commonly represented by
ansible_host. - Primary group
- The main target group that receives every accepted host row.
- Group variables
- Shared values placed under a
:varssection, such as login user, connection type, or platform settings.
Grouping is the main reason to write inventory instead of pasting a list of addresses into a command. A host can belong to a primary group such as edge_routers while also appearing in groups for site, platform, role, or environment. A parent children group can gather several smaller groups into a broader target, so a playbook can say what it intends to change without duplicating host rows.
Variables need careful placement. Host variables belong on a host line when the value is unique, such as a nonstandard SSH port. Group variables belong in a :vars section when the value applies to every member of the primary group. Secrets are a poor fit for static inventory text because copied output, review tables, and screenshots can expose them. Use vaulted variables or another protected workflow for passwords, tokens, and private keys.
A generated inventory is ready for review, not ready for blind execution. It can reduce text mistakes before a change, but only the installed Ansible version on the control node can prove how the file parses, and only a limited connectivity check can prove that DNS, SSH, WinRM, network CLI access, Python paths, collections, and credentials are correct.
How to Use This Tool:
Build the inventory from the target group outward, then use the review output before copying or downloading the INI draft.
- Set
Inventory groupto the primary target you expect to use in playbooks or ad hoc commands, such asedge_routers,prod_linux, orweb. Empty group names and names with whitespace, brackets, colon, or#create blocking errors. - Enter
Host rowsasalias,ansible_host,groups,host_vars, paste rows, drop a CSV or TXT file, or useBrowse CSV. Blank lines, comment lines beginning with#, and a recognizable header row are ignored. - Use the third cell for extra groups. Spaces, pipes, and semicolons split multiple group names, so
dc1|iosanddc1 iosboth create additional group membership. - Put host-specific values after the third comma as
key=valuetokens. Put shared values inGroup variables, onekey=valueentry per line. - Set
Default ansible_userwhen the same login user applies to the primary group. IfGroup variablesalready includesansible_user, the review warns that the group variable takes priority over the default user field. - Open
AdvancedforParent children group, alias sorting, verification comments, or an intentional empty:varssection. UseNormalize rowsafter import when accepted rows need a consistent CSV shape. - Read
Inventory Reviewbefore usingINI Inventory. Red errors leave the INI output empty; yellow warnings still allow output but need operator review. Parse the draft withansible-inventory -i inventory.ini --listbefore running playbooks.
Interpreting Results:
The summary reports status, accepted hosts, the primary group, and remaining warnings. An accepted host count means the rows could be parsed into an inventory draft. It does not prove that the host names resolve, that the login user can authenticate, or that the selected connection plugin works.
Red errors are stop signs. The generated INI text stays empty so a partial inventory is not mistaken for a usable file. Yellow warnings describe choices that may be valid but deserve attention, such as a short alias without a separate ansible_host or a group name that may trigger Ansible naming warnings.
| Result area | What it confirms | What to verify next |
|---|---|---|
INI Inventory |
No blocking review errors remain, so an INI draft could be assembled. | Run ansible-inventory -i inventory.ini --list on the control node. |
Host Ledger |
Accepted aliases, connection addresses, extra groups, host variables, and source line numbers. | Compare missing or unexpected hosts against the original spreadsheet or change list. |
Inventory Review |
Pass, warning, and error messages for group names, host rows, variables, and parent groups. | Fix errors first, then decide whether each warning is intentional. |
JSON |
A structured snapshot of inputs, parsed hosts, generated inventory text, and review rows. | Use it for handoff or audit notes, not as the Ansible inventory source. |
A clean review can still hide environmental problems. Treat the generated text as a draft that has passed local syntax and naming checks, then validate it with Ansible and a limited connectivity command before any change work.
Technical Details:
INI inventory is section based. A [group] section lists hosts, a [group:vars] section assigns values to every member of that group, and a [parent:children] section lists child groups rather than host lines. The inventory alias becomes Ansible's host identity, while variables such as ansible_host, ansible_port, ansible_user, and ansible_connection affect how Ansible connects.
INI variables have an important type caveat. Inline host variables can be interpreted as Python literal values, while variables in a :vars section are treated as strings. For typed values, nested data, or sensitive material, separate host_vars and group_vars files are usually easier to audit than a dense static INI file.
Transformation Core:
The generator maps each accepted row into one primary host entry, optional extra group membership, optional host variables, and optional shared group variables.
| Input part | INI effect | Review importance |
|---|---|---|
Inventory group |
Creates the primary [group] section and receives every accepted host line. |
This is the main target name for plays and ad hoc commands. |
| Host alias | Becomes the first token on the host line and the inventory host identity. | Aliases must be unique because duplicate aliases are blocking errors. |
ansible_host |
Adds ansible_host=value only when the connection address differs from the alias. |
Short aliases without addresses may depend on local DNS or SSH configuration. |
| Extra groups | Create additional group sections with the same host alias as a member. | Role, site, platform, and environment targeting become visible without duplicate rows. |
| Host variables | Add accepted key=value tokens inline on that host line. |
Use them for values that differ per host, such as nonstandard ports. |
| Group variables | Create or populate [group:vars] for shared values. |
Shared login and connection defaults avoid repeated host-line variables. |
| Parent children group | Creates [parent:children] and lists the primary plus extra groups. |
A broader target can include child groups while keeping smaller groups explicit. |
A row such as edge-rtr-01,10.44.1.11,dc1|ios,site=dc1 role=edge rack=A1 becomes one host under the primary group, two extra group memberships, and three host variables. With a parent group of network, the parent children section includes the primary group plus dc1 and ios.
[edge_routers]
edge-rtr-01 ansible_host=10.44.1.11 site=dc1 role=edge rack=A1
[dc1]
edge-rtr-01
[ios]
edge-rtr-01
[network:children]
edge_routers
dc1
ios
Rule Core:
| Condition | Severity | Correction |
|---|---|---|
| Missing primary group, missing host rows, or no usable parsed hosts | Error | Enter a target group and at least one valid host row. |
Primary, extra, or parent group contains whitespace, brackets, colon, or # |
Error | Use compact group names such as prod_linux or edge_routers. |
| Group name parses but is not identifier-style | Warning | Prefer letters, numbers, and underscores for shared inventories. |
| Duplicate host alias | Error | Keep one row per alias because the alias is Ansible's inventory identity. |
| Unclosed CSV quote or host-variable quote | Error | Close the quote or remove the embedded comma or whitespace from the value. |
Host or group variable lacks valid key=value syntax |
Error | Use valid Ansible variable names and one value per token or line. |
Short alias has no separate ansible_host |
Warning | Add a DNS name or IP address when the alias is not resolvable from the control node. |
Parent children group matches the primary group |
Error | Choose a different parent group or leave the parent field blank. |
Variable Semantics:
| Variable | Typical placement | Reason |
|---|---|---|
ansible_host |
Host line | The connection address often differs for each alias. |
ansible_port |
Host line unless every host shares it | A nonstandard SSH port is usually host-specific. |
ansible_user |
[group:vars] when shared |
A shared login user is easier to review once than repeated on every row. |
ansible_connection |
[group:vars] for platform groups |
SSH, local, WinRM, or network connection behavior often follows platform grouping. |
| Passwords and tokens | Protected variable workflow | Static inventory text is easy to copy, export, commit, or screenshot. |
Variable precedence extends beyond one generated file. Parent groups, child groups, host variables, separate variable files, playbook variables, and command-line variables can all affect the final values Ansible sees. Parse the inventory and inspect final host variables before relying on the draft for operational changes.
Privacy Notes:
Pasted host rows and CSV or TXT imports are read in the browser, and imported files over 1 MiB are rejected. The generated INI, ledger, review rows, JSON snapshot, copied text, downloaded files, and screenshots can still expose hostnames, IP addresses, ports, users, platform names, and variables. Keep secrets out of static inventory text and use Ansible Vault or another protected variable workflow for sensitive values.
Advanced Tips:
- Leave
Include verification commentsenabled when handing the draft to another operator because it keeps the parse command near the generated text. - Use
Host orderby alias only when review readability matters more than preserving the original source-line order. - Turn on
Keep empty :vars sectiononly when you intentionally want a placeholder for later editing. - Use
Normalize rowsafter importing from a spreadsheet so quoted values and accepted group lists are easier to compare. - Move growing platform settings into separate
group_varsfiles once the INI draft stops being short and readable.
Worked Examples:
Network Device Batch
A network change uses edge_routers as the primary group, admin as Default ansible_user, and group variables such as ansible_connection=network_cli and ansible_network_os=cisco.ios.ios. Rows like edge-rtr-01,10.44.1.11,dc1|ios,site=dc1 role=edge produce a primary group entry, extra dc1 and ios sections, and a ledger row tied back to the original source line.
Linux Hosts With A Nonstandard Port
A Linux rollout uses prod_linux, shared ansible_connection=ssh, and ansible_python_interpreter=/usr/bin/python3. A database row such as db-01,10.50.20.31,db|prod,site=dc1 role=postgres ansible_port=2222 keeps the alternate SSH port on that host line because it should not apply to every host in the primary group.
Duplicate Alias Cleanup
Two pasted rows named web-01 create a Duplicate host alias error. INI Inventory stays empty until one alias is changed or one row is removed. After the fix, Host Ledger should show one accepted row for each alias and the expected source line numbers.
FAQ:
Does the inventory draft test host reachability?
No. It validates local text shape and builds an INI draft. Parse it with ansible-inventory -i inventory.ini --list, then run a limited connectivity or facts check from the control node.
Can the alias and ansible_host be different?
Yes. The alias is the inventory identity, while ansible_host is the resolvable name or IP Ansible connects to. This is useful for short aliases, lab names, or addresses that operators do not want as play output names.
What host row format is accepted?
Use alias,ansible_host,groups,host_vars. The groups cell can contain several groups separated by spaces, pipes, or semicolons, and host variables after the third comma must use key=value tokens.
Why does a group name warning appear when output still exists?
Some group names can parse but still be warning-prone in Ansible. The review recommends identifier-style names made from letters, numbers, and underscores so group references stay predictable.
Why is the INI output empty?
At least one blocking error remains, such as a missing primary group, duplicate alias, unsafe group name, invalid variable token, or unclosed quote. Fix the red Inventory Review rows first.
Should passwords or tokens go in host variables?
No. Static inventory text and exported review artifacts are easy to copy or commit. Store sensitive values in vaulted files or another protected variable store instead.
Glossary:
- Control node
- The machine where Ansible runs, parses inventory, and starts connections to managed hosts.
- Inventory alias
- The host identity Ansible uses inside inventory and play output.
ansible_host- The resolvable host name or IP address used when it differs from the inventory alias.
- Primary group
- The main generated group section that receives every accepted host row.
- Extra group
- An additional group assigned from a host row for site, role, platform, or environment targeting.
- Parent children group
- A metagroup section that lists child group names instead of individual hosts.
- Host variables
- Inline variables placed on one host line because the value applies only to that host.
- Group variables
- Shared variables placed under a
[group:vars]section for members of the primary group.
References:
- How to build your inventory, Ansible Community Documentation.
- Build Your Inventory, Ansible Community Documentation.
- Protecting sensitive data with Ansible vault, Ansible Community Documentation.
- How to connect to an SSH server on a different port, Simplified Guide.
- How to set per-host SSH identity files in config, Simplified Guide.