Ansible Fundamentals · Module 05 of 12

Ad-hoc commands

Use one-off module execution for discovery, verification and carefully controlled changes.

Learning objectives

By the end of this module, you should be able to:

  • Read the structure of an ansible ad-hoc command.
  • Choose command versus shell appropriately.
  • Use common builtin modules for safe one-off operations.

Ad-hoc means one task now

The ansible command is useful when you want to execute one module against a host pattern without creating a playbook. Typical uses include connectivity checks, gathering a quick fact, inspecting uptime or performing a small controlled change.

Prefer purpose-built modules

If Ansible has a module for the resource you want to manage, use it instead of wrapping a shell command. Modules understand state and can often report whether a change was required.

command versus shell

ansible.builtin.command executes a command directly and does not process shell operators such as pipes, redirects or variable expansion. ansible.builtin.shell uses a shell and is appropriate only when you genuinely need shell features. The narrower command module is safer by default.

Worked examples

See the idea in practice.

Read-only checks

ansible all -i inventory.ini -m ansible.builtin.ping
ansible web -i inventory.ini -m ansible.builtin.command -a 'uptime'
ansible web -i inventory.ini -m ansible.builtin.command -a 'id'
  • Start with read-only checks.
  • Use a narrower host group instead of all when possible.
  • The command module does not invoke a shell.

Controlled package change

ansible web -i inventory.ini -b -m ansible.builtin.package -a 'name=nginx state=present'
  • -b requests privilege escalation using become.
  • package expresses desired package state.
  • The module can report changed only when installation was required.
Hands-on lab

Lab — Inspect before you change

Goal: Use ad-hoc commands to verify a web group, then install a package using a state-aware module.

STEP 1

Preview the target

ansible web -i inventory.ini --list-hosts
STEP 2

Inspect uptime

ansible web -i inventory.ini -m ansible.builtin.command -a 'uptime'
STEP 3

Install nginx

ansible web -i inventory.ini -b -m ansible.builtin.package -a 'name=nginx state=present'
STEP 4

Run the same change again

ansible web -i inventory.ini -b -m ansible.builtin.package -a 'name=nginx state=present'

Verify

  • The target host list is correct.
  • The first package run may report changed.
  • The second run should normally report no package change if the desired state is already satisfied.

Expected outcome

  • nginx is installed on the web group.
  • The learner observes the difference between a state change and an already-correct state.

If it fails

  • If become fails, verify sudo policy for the remote user instead of adding plaintext passwords to inventory.
  • If the package name differs on the target OS, choose a package available for that platform or make the future playbook conditional.
Real-world connection

Ad-hoc commands are excellent for investigation, but repeatable operational changes should usually graduate into version-controlled playbooks.

Avoid these traps

Common mistakes

  • Using ansible.builtin.shell by default for every task.
  • Running a state-changing ad-hoc command against all hosts without previewing targets.
  • Keeping important one-off commands only in shell history instead of converting recurring procedures into playbooks.
Knowledge check

Can you explain it without looking back?

Open each answer only after you have tried to answer the question yourself.

1When is ansible.builtin.shell justified?

When the operation genuinely requires shell processing such as pipes or redirects and a dedicated module is not more appropriate.

2Why prefer package over 'dnf install' in a command task?

The package module expresses state and is designed for repeatable configuration management.

3What is a good next step when an ad-hoc change becomes routine?

Move it into a reviewed, version-controlled playbook.