LFCE 148 ๐ง Ansible โ Inventory and Config
The inventory and the configuration file are the two inputs that determine what Ansible does and how it does it. The inventory defines the hosts and groups that a playbook can target, along with the variables that describe each host’s connection details and role. The configuration file defines the behavior of the control node itself: where to find the inventory, how many hosts to manage in parallel, whether to gather facts, and how to format the output. Both are plain text, both are version-controllable, and both have a defined precedence order that determines which value wins when the same setting is defined in more than one place.
This chapter covers the inventory formats (INI and YAML), the host and group variables that control connection behavior, the group_vars and host_vars directories that organize variables outside the inventory file, and the ansible.cfg file with its search order and its most important settings.
Key point: The inventory defines the targets and their variables. The ansible.cfg defines the control node’s behavior. When the same variable is defined in multiple places, the last definition wins, and the group_vars and host_vars directories take precedence over the inline inventory variables.
Why inventory and config are separate
The target problem. A playbook is written once and run against different environments. The inventory is the file that changes between environments: the staging inventory lists staging hosts, the production inventory lists production hosts. The playbook references group names, not host names, and the inventory resolves those groups to the actual machines .
The behavior problem. The control node’s behavior is not the same for every project. One project needs 20 parallel forks and fact caching; another needs a single fork for a serial deployment. The ansible.cfg file is the per-project configuration that controls this behavior without changing the playbook or the inventory .
The precedence problem. Ansible has a defined precedence order for both variables and configuration settings. For configuration, the ANSIBLE_CONFIG environment variable wins over the project ansible.cfg, which wins over the home directory ansible.cfg, which wins over /etc/ansible/ansible.cfg . For variables, the more specific definition wins: host variables override group variables, and host_vars files override inline inventory variables .
a. The inventory formats and connection variables
An inventory can be an INI file or a YAML file. The INI format uses group headers in brackets and host lines with key=value connection variables.
[webservers]
web1.example.com ansible_host=10.0.1.10 ansible_port=22 ansible_user=deploy
web2.example.com ansible_host=10.0.1.11 ansible_port=2222 ansible_user=webadmin
[databases]
db1.example.com ansible_host=10.0.2.10 ansible_user=dbadmin
The connection variables control how Ansible reaches each host. ansible_host is the resolvable name or IP, which is useful when the inventory alias is not the actual address. ansible_port changes the SSH port. ansible_user sets the SSH username. ansible_ssh_private_key_file specifies a key file for a host that does not use the default key .
The YAML format is the recommended choice for new inventories because it handles variable types consistently. The INI format parses :vars sections as strings, which means a boolean false becomes the string "FALSE" unless a filter is applied in the playbook .
all:
children:
webservers:
hosts:
web1.example.com:
ansible_host: 10.0.1.10
web2.example.com:
ansible_host: 10.0.1.11
The group names in the inventory are the names referenced in the playbook’s hosts line. A group can have child groups, and the parent-child relationship determines the variable merge order .
b. The group_vars and host_vars directories
The inline inventory variables are convenient for a few settings, but they do not scale. The group_vars and host_vars directories are the standard way to organize variables. The group_vars/all file applies to every host, group_vars/webservers applies to the webservers group, and host_vars/web1.example.com applies to that specific host .
inventory/
hosts.ini
group_vars/
all.yml
webservers.yml
host_vars/
web1.example.com.yml
The variables in these files are YAML, and they can contain lists and dictionaries, which the INI inline format cannot. The load order is: group variables from the inventory file, then group_vars/all, then child group variables, then host variables from the inventory, then host_vars. The later definition wins .
The ansible_group_priority variable controls the merge order for groups of the same level. A higher number means the group is merged later, giving it higher priority. This variable can only be set in the inventory source, not in group_vars .
c. The ansible.cfg file
The configuration file uses INI syntax with sections. The [defaults] section contains the most important settings.
[defaults]
inventory = inventory/
remote_user = deploy
forks = 20
host_key_checking = False
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts_cache
fact_caching_timeout = 3600
[privilege_escalation]
become = True
become_method = sudo
become_user = root
The inventory setting points to the inventory file or directory. The forks setting controls how many hosts are managed in parallel; the default is 5, and a larger fleet benefits from a higher value . The gathering and fact_caching settings control whether facts are collected and whether they are cached between runs. The host_key_checking setting disables the SSH host key prompt, which is appropriate for a lab but not for production.
The [privilege_escalation] section sets the default become behavior, which removes the need to add become: true to every play .
The configuration search order is ANSIBLE_CONFIG, then ./ansible.cfg, then ~/.ansible.cfg, then /etc/ansible/ansible.cfg. The first file found is used, and the others are ignored .
Complete Example Session
# ============================================
# PART 1: THE INI INVENTORY
# ============================================
[webservers]
web1.example.com ansible_host=10.0.1.10 ansible_user=deploy
web2.example.com ansible_host=10.0.1.11 ansible_port=2222
[databases]
db1.example.com ansible_host=10.0.2.10 ansible_user=dbadmin
# ============================================
# PART 2: THE YAML INVENTORY
# ============================================
all:
children:
webservers:
hosts:
web1.example.com:
ansible_host: 10.0.1.10
databases:
hosts:
db1.example.com:
ansible_host: 10.0.2.10
# ============================================
# PART 3: THE GROUP_VARS FILE
# ============================================
# group_vars/all.yml
ansible_user: deploy
ansible_ssh_private_key_file: ~/.ssh/ansible_key
# ============================================
# PART 4: THE HOST_VARS FILE
# ============================================
# host_vars/web1.example.com.yml
ansible_host: 10.0.1.10
ansible_port: 2222
# ============================================
# PART 5: THE ANSIBLE.CFG
# ============================================
[defaults]
inventory = inventory/
forks = 20
host_key_checking = False
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts
[privilege_escalation]
become = True
become_user = root
# ============================================
# PART 6: VERIFY THE INVENTORY
# ============================================
ansible-inventory --list -i inventory/
ansible all -m ping
# ============================================
# PART 7: THE PRECEDENCE CHECK
# ============================================
# host_vars/web1.example.com.yml defines ansible_port: 2222
# group_vars/all.yml defines ansible_port: 22
# Result: 2222, because host_vars wins.
# ============================================
# PART 8: THE CONFIG SEARCH ORDER
# ============================================
# 1. ANSIBLE_CONFIG
# 2. ./ansible.cfg
# 3. ~/.ansible.cfg
# 4. /etc/ansible/ansible.cfg
# The first one found is used.
# ============================================
# PART 9: THE DYNAMIC INVENTORY
# ============================================
# A plugin source instead of a static file.
# The plugin queries the cloud API.
# ansible-inventory --list shows the result.
# ============================================
# PART 10: THE COMPLETE PROJECT
# ============================================
# project/
# ansible.cfg
# inventory/
# hosts.ini
# group_vars/all.yml
# host_vars/web1.example.com.yml
# site.yml
The ten parts covered the INI inventory, the YAML inventory, the group_vars file, the host_vars file, the ansible.cfg, the inventory verification, the precedence check, the config search order, the dynamic inventory, and the complete project.
Quick Reference
Inventory formats
| Format | Variable typing | Recommended |
|---|---|---|
| INI | Strings in :vars, literals inline | Legacy |
| YAML | Consistent typing | New projects |
| Dynamic plugin | From cloud API | Dynamic environments |
Connection variables
| Variable | Purpose |
|---|---|
ansible_host | IP or hostname to connect to |
ansible_port | SSH port |
ansible_user | SSH username |
ansible_ssh_private_key_file | SSH key path |
ansible_python_interpreter | Python path on the target |
ansible_connection | Connection plugin (ssh, winrm) |
Variable precedence (lowest to highest)
| Order | Source |
|---|---|
| 1 | Group vars in inventory |
| 2 | group_vars/all |
| 3 | Child group vars |
| 4 | Host vars in inventory |
| 5 | host_vars/ |
ansible.cfg search order
| Order | Location |
|---|---|
| 1 | ANSIBLE_CONFIG env var |
| 2 | ./ansible.cfg |
| 3 | ~/.ansible.cfg |
| 4 | /etc/ansible/ansible.cfg |
Key ansible.cfg settings
| Setting | Purpose |
|---|---|
inventory | Path to inventory file or directory |
forks | Parallel hosts (default 5) |
remote_user | Default SSH user |
host_key_checking | SSH host key verification |
gathering | Fact gathering mode |
fact_caching | Fact cache plugin |
Best Practices
โ Do This:
# Use YAML inventory for consistent typing
all:
children:
webservers:
hosts:
web1.example.com:
ansible_host: 10.0.1.10 # โ
# Use group_vars and host_vars for variables
# group_vars/all.yml
ansible_user: deploy # โ
# Set forks for larger fleets
forks = 20 # โ
# Enable fact caching
gathering = smart
fact_caching = jsonfile # โ
โ Don’t Do This:
# Rely on INI :vars for typed values
[all:vars]
my_bool=FALSE # parsed as the string "FALSE" # โ
# Disable host key checking in production
host_key_checking = False # โ
# Put all variables in the inventory file
# Use group_vars and host_vars instead # โ
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Hosts not found | Inventory path wrong in ansible.cfg | Check inventory = inventory/ |
| Connection fails | ansible_user or key not set | Set in group_vars or host_vars |
| Variable type is wrong | INI :vars parses as string | Use YAML inventory or a filter |
| Config not applied | A different ansible.cfg is found first | Check the search order; use ANSIBLE_CONFIG |
| Group variable overridden | Host variable defined | Check precedence; host wins |
| Parallelism too low | Default forks = 5 | Increase forks in ansible.cfg |
Real-World Examples
1. INI inventory with connection vars
[webservers]
web1.example.com ansible_host=10.0.1.10 ansible_user=deploy
2. YAML inventory
all:
children:
webservers:
hosts:
web1.example.com:
ansible_host: 10.0.1.10
3. group_vars/all.yml
ansible_user: deploy
ansible_ssh_private_key_file: ~/.ssh/ansible_key
4. host_vars/web1.example.com.yml
ansible_port: 2222
5. ansible.cfg inventory
[defaults]
inventory = inventory/
6. ansible.cfg forks
forks = 20
7. ansible.cfg fact caching
gathering = smart
fact_caching = jsonfile
8. The config search order
ANSIBLE_CONFIG โ ./ansible.cfg โ ~/.ansible.cfg โ /etc/ansible/ansible.cfg
9. The precedence check
ansible-inventory --list -i inventory/
10. The ping test
ansible all -m ping
Visual
The inventory and config relationship
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ansible.cfg โ
โ โโโ inventory = inventory/ โ
โ โโโ forks = 20 โ
โ โโโ become = True โ
โ โ โ
โ โผ โ
โ inventory/ โ
โ โโโ hosts.ini โ
โ โโโ group_vars/ โ
โ โ โโโ all.yml โ
โ โโโ host_vars/ โ
โ โโโ web1.example.com.yml โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The variable precedence
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Lowest: Group vars in inventory โ
โ group_vars/all โ
โ Child group vars โ
โ Host vars in inventory โ
โ Highest: host_vars/ โ
โ โ
โ The later definition wins. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The config search order
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. ANSIBLE_CONFIG (env var) โ
โ 2. ./ansible.cfg โ
โ 3. ~/.ansible.cfg โ
โ 4. /etc/ansible/ansible.cfg โ
โ โ
โ The first file found is used. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The connection variables
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ansible_host โโโบ the IP or hostname โ
โ ansible_port โโโบ the SSH port โ
โ ansible_user โโโบ the SSH user โ
โ ansible_ssh_private_key_file โโโบ the key path โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| Inventory formats | INI, YAML, dynamic plugin |
| YAML recommendation | Consistent variable typing |
| Connection variables | ansible_host, ansible_port, ansible_user |
| Variable directories | group_vars/, host_vars/ |
| Variable precedence | Host vars override group vars |
| Config file | ansible.cfg |
| Config search order | ANSIBLE_CONFIG, ./, ~/, /etc/ansible/ |
| Parallelism | forks (default 5) |
| Fact caching | gathering, fact_caching |
Key takeaways:
- The inventory defines the targets and their connection details. The INI format is the legacy format; the YAML format is recommended for new inventories because it handles variable types consistently . The connection variables (
ansible_host,ansible_port,ansible_user) override the defaults for each host . - The
group_varsandhost_varsdirectories organize variables outside the inventory. Thegroup_vars/allfile applies to every host, thegroup_vars/<group>file applies to a group, and thehost_vars/<host>file applies to a single host. The more specific definition wins . - The
ansible.cfgfile controls the control node’s behavior. Theinventorysetting points to the inventory, theforkssetting controls parallelism, and thegatheringandfact_cachingsettings control fact collection. The file is searched in a defined order, and the first match wins . - The
ANSIBLE_CONFIGenvironment variable overrides all other config locations. It is the mechanism for using a different configuration file for a specific run without modifying the project’sansible.cfg. - The
ansible_group_priorityvariable controls group merge order. A higher number means the group is merged later, giving it higher priority. It can only be set in the inventory source, not ingroup_vars. - The inventory and config are both version-controlled artifacts. The inventory changes between environments, and the config changes between projects. Keeping both in the repository makes the deployment reproducible and reviewable.
Remember: The inventory is the target list, and the ansible.cfg is the behavior list. The inventory defines the hosts, the groups, and the connection variables. The ansible.cfg defines where the inventory lives, how many hosts to manage in parallel, and how facts are gathered. The group_vars and host_vars directories organize the variables that describe each host’s role and configuration. The precedence order determines which value wins when the same setting is defined in more than one place. Get the inventory right first, because a playbook with no targets does nothing. Then tune the ansible.cfg for the fleet size and the network conditions.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!