Expert · Ansible fundamentals · topic 45 of 57 · 35 min
Inventory and ansible.cfg
Explanation
The inventory
Ansible needs to know which machines exist and how to group them. Groups let you say "install httpd on webservers" instead of naming each host. A host can be in many groups. Two groups always exist: all (every host) and ungrouped (hosts in no other group).
# inventory (INI format)
bastion.example.com
[webservers]
web[01:03].example.com
[dbservers]
db01.example.com ansible_host=10.0.5.20
[datacenter_mumbai:children]
webservers
dbservers# inventory.yml (the same in YAML)
all:
hosts:
bastion.example.com:
children:
webservers:
hosts:
web[01:03].example.com:
dbservers:
hosts:
db01.example.com:
ansible_host: 10.0.5.20
datacenter_mumbai:
children:
webservers:
dbservers:$ ansible-inventory -i inventory --graph
@all:
|--@ungrouped:
| |--bastion.example.com
|--@datacenter_mumbai:
| |--@webservers:
| | |--web01.example.com
| | |--web02.example.com
| | |--web03.example.com
| |--@dbservers:
| | |--db01.example.com
$ ansible webservers -i inventory --list-hosts
hosts (3):
web01.example.com
web02.example.com
web03.example.comansible.cfg: your project settings
Ansible reads settings from ansible.cfg. It uses ONLY the first file it finds, in this order: the file named in the ANSIBLE_CONFIG environment variable, ansible.cfg in the current directory, ~/.ansible.cfg, then /etc/ansible/ansible.cfg. Most teams keep an ansible.cfg in each project directory and run Ansible from there. ansible --version shows which file is in use.
# ~/project/ansible.cfg
[defaults]
inventory = ./inventory
remote_user = devops
host_key_checking = False
[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = FalsePreparing the managed nodes
Ansible logs in over SSH as remote_user. The usual setup: create a dedicated user (for example devops) on every managed node, install the control node's SSH public key for it, and give it passwordless sudo with a sudoers drop-in. You will often do this once by hand or with a first playbook that uses a password.
# on each managed node, as root:
useradd devops
echo 'devops ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/devops
chmod 440 /etc/sudoers.d/devops
# on the control node, as your user:
ssh-copy-id devops@web01.example.com
ansible all -m ansible.builtin.pingCommon mistakes
- Running Ansible from a different directory, so a different ansible.cfg (or none) is used and the inventory is "empty". Check ansible --version.
- Indentation errors in YAML inventories. Use ansible-inventory --graph to see what Ansible understood.
- Writing group names with dashes (web-servers). Ansible warns; use underscores.
- Forgetting that :children lists GROUPS, not hosts.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Inventory and ansible.cfg · 1/6
The inventory lists hosts in groups. Groups let you target many hosts by one name.
Prefer a video by a teacher? Find free videos on “ansible inventory ansible.cfg tutorial groups children become” on YouTube ↗
In real life: One inventory for two data centres at a telecom company
A telecom company has servers in Mumbai and Hyderabad. The inventory groups hosts by role (webservers, dbservers) AND by place (dc_mumbai, dc_hyderabad, using :children). During a Mumbai network maintenance, the team runs playbooks with --limit dc_hyderabad, and when only databases need a change, they target dbservers in both places.
$ ansible-playbook site.yml --limit dc_hyderabad
$ ansible 'dbservers:&dc_mumbai' --list-hosts
hosts (2):
db01.mum.example.com
db02.mum.example.comPractice (0/3 done)
Which ansible.cfg is used when you run ansible from ~/project, which contains its own ansible.cfg, and ANSIBLE_CONFIG is not set?
Write parse_inventory(text) for a simple INI inventory. Return a dict mapping group name to a list of host names, in file order. Hosts before any [group] go in "ungrouped". Ignore blank lines and lines starting with # or ;. For a host line, keep only the first word (drop variables like ansible_host=...). For [name:children] sections, store the child group names under "name" too. Ignore [name:vars] sections.
Set up a control node and two managed nodes (three VMs, or one VM managing itself plus localhost). Create ~/ansible/ with an inventory (groups dev and prod, plus a group webservers containing both as children) and an ansible.cfg using a devops user with become. Prove it with --graph and a ping.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Ad-hoc commands and ansible-docAnsible fundamentals · same module
- Writing and running playbooksAnsible fundamentals · same module
- Ansible: inventory and ad-hoc commandsDevOps: Git, Docker, Kubernetes and CI/CD · Configuration management with Ansible, and YAML
- Variables, facts and registered resultsAnsible in depth
- RHCE (EX294): automation with AnsibleCertifications and career
- Ansible playbooksDevOps: Git, Docker, Kubernetes and CI/CD · Configuration management with Ansible, and YAML
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
What does web[01:03].example.com mean in an inventory?
Answer: web01, web02 and web03
It is a numeric range pattern.
Which group contains every host?
Answer: all
all always exists.
In ansible.cfg, what does become = True do?
Answer: Uses privilege escalation (sudo by default) on managed nodes
Tasks run as become_user (root) via sudo.
Which command shows the inventory as a tree?
Answer: ansible-inventory --graph
--graph prints groups and hosts.
Why is host_key_checking = False risky in production?
Answer: Ansible would not notice if it connected to an impostor host
Host key checks protect against man-in-the-middle attacks.
In an INI inventory, what does [prod:children] define?Related
Answer: A group whose members are other groups
:children makes a group of groups.
Which package gives you ansible-playbook on RHEL 9?Related
Why quote "{{ inventory_hostname }}" at the start of a YAML value?Related
Answer: YAML would read { as the start of a dictionary
Quote values starting with {{.
Which magic variable holds the host's name as written in the inventory?Related
Answer: inventory_hostname
inventory_hostname; ansible_facts['hostname'] is what the host reports itself.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 3 more topics in “Ansible fundamentals” before its exam: Ad-hoc commands and ansible-doc, Writing and running playbooks, Everyday modules and handlers.
- Module 9 exam: Ansible fundamentals · 14 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Ansible in depth. 57 topics left in the course before the final exam.