Skip to content

Intermediate · Configuration management with Ansible, and YAML · topic 35 of 53 · 30 min

Ansible: inventory and ad-hoc commands

Explanation

Configuration management keeps many servers in a known, desired state: the right packages, files, users and services. Ansible does this without installing an agent: a control node connects to managed nodes over SSH, pushes small programs called modules, and runs them. The inventory lists your servers in groups. Modules are idempotent, so a second run reports "ok" instead of "changed".

The idea of configuration management

Terraform creates servers. Something must then install nginx, copy config files, create users and start services, on every server, the same way. Doing this by hand over SSH on 50 servers is slow and each server ends up a little different. Configuration management tools describe the desired state ("nginx is installed and running, this file has this content") and make every server match it.

Think of it like this: Think of a hotel housekeeping checklist: every room must have two towels, a clean bedsheet, soap and a water bottle. The housekeeper does not care what the room looked like before; she brings each room to the checklist. If a room already matches, she moves on. Ansible is the housekeeper, the playbook is the checklist, and the rooms are your servers.

How Ansible works

  • Control node: the machine where Ansible is installed and where you run commands (your laptop, a CI runner or a jump server). It must be Linux or macOS; on Windows use WSL.
  • Managed nodes: the servers Ansible configures. Nothing extra is installed on them. Linux nodes need SSH and Python. Windows nodes are reached with WinRM or PSRP instead of SSH.
  • Inventory: a file that lists the managed nodes, in groups.
  • Modules: small programs for one job (install a package, copy a file, start a service). Ansible copies the module to the node over SSH, runs it and removes it.
  • Push model: the control node pushes changes when you run it. Chef and Puppet traditionally use agents that pull from a server.

Because there is no agent to install or patch, Ansible is easy to start with. It is owned by Red Hat and is open source. You install it with pip install ansible (or your OS package manager). The ansible package includes ansible-core plus many collections of modules.

The inventory

An inventory lists hosts (servers) and groups them. INI format is short and common. A host line can carry variables such as ansible_host (the real address) and ansible_user (the SSH user). [group:vars] sets variables for a whole group, and [group:children] makes a group of groups. Two groups always exist: all (every host) and ungrouped (hosts in no other group).

ini
# inventory.ini
[web]
web1.college.edu ansible_host=10.0.1.11
web2.college.edu ansible_host=10.0.1.12

[db]
db1.college.edu ansible_host=10.0.2.21

[prod:children]
web
db

[web:vars]
ansible_user=deploy
prod contains every host in web and db.
yaml
all:
  children:
    web:
      hosts:
        web1.college.edu:
          ansible_host: 10.0.1.11
        web2.college.edu:
          ansible_host: 10.0.1.12
      vars:
        ansible_user: deploy
    db:
      hosts:
        db1.college.edu:
          ansible_host: 10.0.2.21
The same inventory in YAML format.
bash
ansible-inventory -i inventory.ini --graph   # show groups and hosts as a tree
ansible-inventory -i inventory.ini --list    # show everything as JSON
Check what Ansible understands from your inventory.

Ad-hoc commands

An ad-hoc command runs one module on a group of hosts, straight from the command line. It is useful for quick checks and one-off jobs. For anything you will repeat, write a playbook (next lesson).

bash
ansible all -i inventory.ini -m ansible.builtin.ping
ansible web -i inventory.ini -m ansible.builtin.apt -a "name=nginx state=present update_cache=true" --become
ansible web -i inventory.ini -m ansible.builtin.service -a "name=nginx state=restarted" --become
ansible db -i inventory.ini -m ansible.builtin.command -a "df -h"
-m picks the module, -a passes its arguments, --become runs it with sudo.

The ping module is not a network ping. It logs in over SSH, checks that Python works, and answers "pong". Write modules with their fully qualified collection name (FQCN), such as ansible.builtin.apt: the collection (ansible.builtin) plus the module name. Short names like apt still work, but FQCNs avoid clashes between collections.

ok, changed and idempotency

Each module checks the current state first. If nginx is already installed, the apt module does nothing and reports ok (green). If it had to install it, it reports changed (yellow). Failures are red. Run the same command twice: the second run should be all ok. This idempotency is what makes Ansible safe to rerun.

output
web1.college.edu | CHANGED => { "changed": true, ... }
web2.college.edu | SUCCESS => { "changed": false, ... }
web1 needed nginx installed; web2 already had it.
Careful: ansible.builtin.command and ansible.builtin.shell are NOT idempotent: they run every time and report changed. Prefer a dedicated module (apt, copy, service, user) whenever one exists.

ansible.cfg

ansible.cfg holds settings so you do not type them every time, for example the inventory path and the remote user. Ansible looks for it in this order: the ANSIBLE_CONFIG environment variable, ansible.cfg in the current folder, ~/.ansible.cfg, and /etc/ansible/ansible.cfg.

ini
[defaults]
inventory = ./inventory.ini
remote_user = deploy
A small project ansible.cfg.

Common mistakes

Careful: SSH problems look like Ansible problems. If ping fails with UNREACHABLE, first try ssh deploy@10.0.1.11 by hand. Check the user, the key and the host key prompt.
Careful: Forgetting --become (sudo) for tasks that need root, such as installing packages. The error is usually a permission denied message.

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

Ansible: inventory and ad-hoc commands · 1/7

Ansible basics

In this lesson you will meet Ansible, a tool that keeps many servers in the same desired state.

Prefer a video by a teacher? Find free videos on “ansible tutorial for beginners inventory ad hoc commands” on YouTube ↗

In real life: Patching 40 branch servers at a cooperative bank

A cooperative bank in Gujarat has a small Linux server in each of its 40 branches. The IT team keeps an inventory grouped by region. When a security fix for OpenSSL is released, one ad-hoc command checks the installed version on every branch, and a short playbook upgrades the package region by region. Servers that are already patched report ok and are left alone.

bash
ansible branches_north -m ansible.builtin.command -a "openssl version"
ansible branches_north -m ansible.builtin.apt -a "name=openssl state=latest update_cache=true" --become
Check first, then fix, one group at a time.

Practice (0/3 done)

Task 1 · Question

What must be installed on a managed Linux node for Ansible to work?

Task 2 · Code · Python

Parse a simple INI inventory. Write parse_inventory(text) that returns a dict {group: [hosts]}. - [name] starts a host group; each following line is a host, and only its first word is the host name (ignore variables like ansible_host=...). - [name:children] starts a group of groups; each line is a child group name. The parent group's hosts are all hosts of its children, in order, without duplicates. - [name:vars] sections are ignored. - Blank lines and lines starting with # or ; are ignored. - Hosts before any [section] belong to the group "ungrouped".

Task 3 · Question

You run the same apt install command twice. The first run says CHANGED. What should the second run say?

Quick quiz

Question 1

1.How does Ansible usually connect to Linux servers?

Question 2

2.What does ansible all -m ansible.builtin.ping check?

Question 3

3.In an INI inventory, what does [prod:children] define?

Question 4

4.Why prefer ansible.builtin.apt over ansible.builtin.shell with "apt-get install -y nginx"?

Question 5

5.What does --become do in an Ansible command?

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.

How does Ansible usually connect to Linux servers?

Answer: Over SSH

Ansible is agentless and uses SSH for Linux (WinRM or PSRP for Windows).

What does ansible all -m ansible.builtin.ping check?

Answer: That Ansible can log in and run Python on each host

The ping module tests the SSH login and Python, and replies pong.

In an INI inventory, what does [prod:children] define?

Answer: A group whose members are other groups

:children makes a group of groups.

Why prefer ansible.builtin.apt over ansible.builtin.shell with "apt-get install -y nginx"?

Answer: apt is idempotent and reports changed only when it really changes something

shell runs every time and always reports changed; the apt module checks state first.

What does --become do in an Ansible command?

Answer: Runs the task with higher privileges, by default using sudo

become escalates privileges, usually to root via sudo.

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

Answer: Uses privilege escalation (sudo by default) on managed nodes

Tasks run as become_user (root) via sudo.

From Inventory and ansible.cfg

What does "ansible all -m ansible.builtin.ping" check?Related

Answer: That Ansible can log in over SSH and run Python on each host

It is a module round-trip, not ICMP.

From Ad-hoc commands and ansible-doc

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

Answer: ansible-core

ansible-core.

From What Ansible is and how it works

Two tasks notify "Reload nginx" and both report changed. How many times does the handler run on that host?Related

Answer: Once, at the end of the play

Handlers are deduplicated and run once, after the tasks of the play.

From Ansible playbooks

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. 2 more topics in “Configuration management with Ansible, and YAML” before its exam: Ansible playbooks, Roles, templates, Galaxy and Vault.
  2. Module 8 exam: Configuration management with Ansible, and YAML · 13 questions · 20 min, without help. 4 topics of this module still to finish first.
  3. Then the next module, Monitoring and logging. 53 topics left in the course before the final exam.

← Previous: YAML in depth