Skip to content

Expert · Ansible fundamentals · topic 45 of 57 · 35 min

Inventory and ansible.cfg

Explanation

The inventory lists your managed hosts in groups, in INI or YAML format; groups can contain other groups. ansible.cfg sets defaults such as which inventory to use, the remote user and privilege escalation (become). Ansible uses the first ansible.cfg it finds: $ANSIBLE_CONFIG, then ./ansible.cfg, then ~/.ansible.cfg, then /etc/ansible/ansible.cfg.

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).

ini
# 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
web[01:03] is a range: web01, web02, web03. :children makes a group of groups. ansible_host sets the address to connect to.
yaml
# 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:
bash
$ 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.com
Always check a new inventory with --graph or --list-hosts.

ansible.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.

ini
# ~/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 = False
become = True means "use sudo to become root on the managed node".

Preparing 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.

bash
# 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.ping
Careful: host_key_checking = False skips the "do you trust this host key?" question. It is convenient in a lab, but in production it removes protection against connecting to an impostor server. In production, collect the host keys properly (ssh-keyscan into known_hosts) and keep checking on.

Common 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

[webservers] web[01:03].example.com

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.

bash
$ ansible-playbook site.yml --limit dc_hyderabad
$ ansible 'dbservers:&dc_mumbai' --list-hosts
  hosts (2):
    db01.mum.example.com
    db02.mum.example.com
dbservers:&dc_mumbai means hosts in BOTH groups.

Practice (0/3 done)

Task 1 · Question

Which ansible.cfg is used when you run ansible from ~/project, which contains its own ansible.cfg, and ANSIBLE_CONFIG is not set?

Task 2 · Code · Python

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.

Task 3 · Practice

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

Question 1

1.What does web[01:03].example.com mean in an inventory?

Question 2

2.Which group contains every host?

Question 3

3.In ansible.cfg, what does become = True do?

Question 4

4.Which command shows the inventory as a tree?

Question 5

5.Why is host_key_checking = False risky in production?

Read more (free)

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.

From Ansible: inventory and ad-hoc commands

Which package gives you ansible-playbook on RHEL 9?Related

Answer: ansible-core

ansible-core.

From What Ansible is and how it works

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 {{.

From Writing and running playbooks

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.

From Variables, facts and registered results

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

  1. 3 more topics in “Ansible fundamentals” before its exam: Ad-hoc commands and ansible-doc, Writing and running playbooks, Everyday modules and handlers.
  2. Module 9 exam: Ansible fundamentals · 14 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Ansible in depth. 57 topics left in the course before the final exam.

← Previous: What Ansible is and how it works