Inventory, modules and ad-hoc commands
The inventory lists the machines Ansible manages, sorted into groups. Modules are the units of work, such as copy, file, package or service. You can run a single module against a group straight from the command line, which is called an ad-hoc command.
The inventory
An inventory names the managed nodes and puts them into groups, so that you can target 'all web servers' or 'the test z/OS systems' in one word. The simplest form is an INI file:
[web] web01.example.com web02.example.com [zos_test] zt01 ansible_host=zt01.example.com ansible_user=ansibl1 [test:children] web zos_test
[web] is a group. ansible_host and ansible_user are host variables telling Ansible how to connect. [test:children] makes a group of groups. The same inventory can be written in YAML, and in large companies it is often generated from a cloud provider or an asset database.
Modules
A module does one job and reports whether it changed anything. Modules have fully qualified names, written collection first, such as ansible.builtin.copy. Some you will see constantly:
| Module | What it ensures |
|---|---|
ansible.builtin.ping | Ansible can connect and Python works (it is not a network ping) |
ansible.builtin.package | A software package is present or absent |
ansible.builtin.copy | A file on the node has the given content |
ansible.builtin.template | A file is generated from a template filled with variables |
ansible.builtin.file | A file, folder or link exists, with the right owner and permissions |
ansible.builtin.service | A service is started, stopped or enabled at boot |
ansible.builtin.command / shell | Runs a command. The fallback when no module fits |
ansible-doc ansible.builtin.copy prints any module's documentation and examples, right in the terminal.
Ad-hoc commands
$ ansible web -i inventory.ini -m ansible.builtin.ping web01.example.com | SUCCESS => { "changed": false, "ping": "pong" } web02.example.com | SUCCESS => { "changed": false, "ping": "pong" } $ ansible web -i inventory.ini -b -m ansible.builtin.service -a "name=nginx state=restarted"
The pattern is ansible GROUP -i INVENTORY -m MODULE -a "ARGUMENTS". -b (become) runs the task with elevated rights through sudo. Ad-hoc commands are good for quick checks and one-off fixes. Anything you will do twice belongs in a playbook.
Which module do you run ad hoc to check that Ansible can reach a group of machines? (fully qualified name)
Show a hint
It answers pong.
Show the solution
ansible.builtin.ping. It replies pong when the connection and Python work.
Examples are for learning. Run commands and jobs only on a system you are authorised to use, such as a training or test system, and never on production without approval.
Common mistakes
It logs in over SSH and runs Python. 'pong' proves Ansible can work there, which a network ping cannot.
Shell tasks are never idempotent by default and always report 'changed'. Look for a module first.
ansible all ... hits every machine in the inventory. Check the group name before pressing Enter.
What you will see at work
- Inventories usually split by environment, for example test and production, so a test run cannot touch production.
- The first thing to check when Ansible 'cannot reach' a host is whether you can ssh to it as the same user.
- Teams agree to use fully qualified module names, which avoids clashes between collections.
Key terms
Check your understanding.
Take this lesson's quiz and save your progress. Free.