Courseiva
EX294Chapter 4 of 18Objective 3.1

Ansible Modules and Ad Hoc Commands

Ansible modules and ad hoc commands. They are the building blocks and the quick-fix tools that let you manage hundreds of servers from a single terminal without logging in manually. For the EX294 exam, you must understand how to use these to perform immediate tasks and how they fit into the larger automation framework.

12 min read
Beginner
Updated Jul 23, 2026
Editorial oversight: Johnson Ajibi· Security Systems Architect · MSc IT Security · IEEE Senior Member

A simple way to picture Ansible Modules and Ad Hoc Commands

The 12-Ingredient Recipe Analogy

You have a recipe that calls for 12 ingredients to make a lasagna. You have already prepared the tomato sauce, grated the cheese, and boiled the noodles. Now the recipe says: "Spread a layer of sauce over the noodles." This is a specific module in your cooking playbook. Now imagine you don't want to cook the whole lasagna; you just want to taste the sauce to check the salt. You reach into the bowl, dip in a spoon, and taste it immediately. That single, one-off taste test is an ad hoc command. You are not following the full recipe; you are performing one small, immediate action. In IT, managers often need to check a single setting on a server without running the entire automation script. An ad hoc command is that single spoonful — quick, direct, no ceremony. The complete recipe, with all its steps, is like a playbook. The individual action of spreading sauce is a module. When a system administrator wants to see if a service is running on 200 servers, they use an ad hoc command with the service module. They give one instruction: "Check the status of the httpd service." That is the exact equivalent of tasting the sauce. No full meal, just one quick check. This analogy is specific because lasagna recipes have many discrete steps (modules) and you sometimes just want one taste (ad hoc command) without cooking the whole dish. Other IT analogies (like a traffic cop) are too generic and don't capture the "one quick action versus a full procedure" distinction.

Now imagine you taste the sauce and it is bland. You do not rewrite the entire recipe; you add a pinch of salt. That is another ad hoc command: "Add salt to the sauce." In IT, if a server's time is off, you do not rewrite the entire configuration management script; you run an ad hoc command to synchronise the clock. The module is the action (spreading sauce, adding salt, checking time). The ad hoc command is the decision to do only that one action right now.

How It Actually Works

Ansible is an automation tool. It runs on your control node (your laptop or a management server) and connects to managed nodes (the servers you want to configure). It uses SSH, a secure way to log into remote computers. Ansible modules are pre-written pieces of code that perform a specific task. For example, the copy module copies a file from the control node to the managed node. The yum module installs or removes software on systems that use the yum package manager (like Red Hat Enterprise Linux). The service module starts, stops, or checks the status of a service (like a web server).

An ad hoc command is a single Ansible command that runs one module against one or many managed nodes. You do not write a full script (called a playbook). You type a command directly in your terminal. The structure is: ansible [target] -m [module] -a '[module arguments]'. The target can be a hostname, a group of hosts defined in your inventory file, or the keyword all to run on every managed node. -m specifies the module. -a passes arguments to that module.

Why does this exist? Before automation, administrators would SSH into each server individually, run commands, and repeat for every machine. That is slow, error-prone, and boring. Ad hoc commands let you change 50 servers at once with one line. Modules ensure the task is done correctly every time because they are tested code, not a human typing commands by memory.

Here are the most common modules tested on EX294:

command: runs a simple command on the managed node. It does not process the command through the shell, so variables and redirects do not work.

shell: runs a command through the shell, so pipes, redirects, and environment variables work.

copy: copies a file from the control node to the managed node.

file: manages file attributes like permissions, ownership, and whether the path is a file or directory.

yum: installs, removes, updates, or queries packages using the yum package manager.

service: manages services: start, stop, restart, enable (start on boot), or check status.

user: creates, modifies, or deletes user accounts.

ping: tests connectivity to managed nodes. It does not ping like ICMP; it connects via SSH and returns a success message.

When you run an ad hoc command, Ansible connects to each node, transfers the module code (a small Python script) to the node, executes it there, and returns the result. The module runs on the managed node, not the control node. That is important for the exam: modules are idempotent wherever possible. Idempotent means running the module multiple times has the same effect as running it once. If a package is already installed, the yum module will not reinstall it; it will report "success" but do nothing. This is a huge advantage over shell scripts that might break something if run twice.

Ad hoc commands are not ideal for complex tasks because you cannot use conditionals, loops, or variables easily. For that, you write a playbook. But for quick checks, restarting a service across 100 servers, or patching a single issue, ad hoc commands are perfect.

On the EX294 exam, you will be asked to write ad hoc commands that use specific modules with correct arguments. You must know the module names and what they do. You must also know the difference between the command and shell modules. The command module is safer because it does not interpret shell syntax. The shell module is more flexible but riskier. The exam often tests this distinction.

You also need to understand the ansible command's flags. The -k flag asks for the SSH password (never use in production; use SSH keys). -b or --become runs the module with privilege escalation (like sudo). -K asks for the become password. -i specifies the inventory file. -u specifies the remote user. You must know these for the exam.

Finally, know the setup module. This gathers facts about the managed node (OS version, IP address, CPU architecture, etc.) and returns them as variables. You can run it with ansible all -m setup to see everything about your nodes. Facts are used in playbooks to make decisions based on the target system's configuration.

Ansible control node connects to multiple managed nodes via SSH and runs modules directly on each node.

Walk-Through

1

Decide on the target hosts

Identify the managed nodes you want to affect. They are defined in your inventory file. You can target a single host by its hostname, a group by its group name, or use the keyword `all` for every host. This determines the first part of your ad hoc command: `ansible all` or `ansible webservers`.

2

Choose the correct module

Select the module that performs the specific task you need. If you are managing software packages, choose `yum`. If you are managing files, choose `copy` or `file`. If you are checking a service, choose `service`. The wrong module will not do what you expect. Memorise the common modules and their purposes.

3

Supply module arguments with `-a`

Arguments tell the module exactly what to do. For the `service` module, arguments are `name=httpd state=started`. For the `yum` module, `name=nginx state=present`. Wrap the arguments in single quotes: `-a 'name=httpd state=started'`. If you omit the quotes, the shell may misinterpret spaces.

4

Add privilege escalation if needed

Many system tasks require root or sudo privileges. Add `--become` to your command to escalate privileges. If you need to provide a password for escalation, add `--ask-become-pass` (often written as `-K`). Do not forget this step: an ad hoc command that tries to install a package without `--become` will fail with a permission error.

5

Execute the command and interpret the output

Press Enter. Ansible connects to each target node, runs the module, and returns a summary. A green or "ok" result means the desired state was already present. A yellow "changed" result means Ansible had to make a change. A red "failed" result means something went wrong — read the error message to troubleshoot.

What This Looks Like on the Job

Alice is a junior system administrator at a mid-sized company that runs 150 Linux servers. A developer reports that a web application on the production server is returning errors. Alice needs to check if the Apache web server (the httpd service) is running on all 150 application servers. She does not want to SSH into each one — that would take hours. She opens her terminal, types ansible app-servers -m service -a 'name=httpd state=started' and presses Enter. In 10 seconds, Ansible connects to every server in the app-servers group, checks if httpd is running, and returns a colour-coded result for each. One server shows red: the service is stopped. She then runs ansible app-servers -m service -a 'name=httpd state=started' again, and this time the failed server turns green. The problem is solved in under a minute.

Later that week, the security team mandates that the root user must be renamed on all database servers. Alice does not want to write a full playbook for this one-time change. She uses the user module: ansible db-servers -m user -a 'name=root uid=0 state=present'. Wait — that does not rename the user. She needs to create a new user, then lock the old one. She runs two ad hoc commands:

ansible db-servers -m user -a 'name=legacy_admin uid=0 state=present'

ansible db-servers -m command -a 'passwd -l root'

She locks the root account by running the passwd -l command via the command module. She uses command because it is a one-off system command, not a standard Ansible operation. She did not need a playbook; two ad hoc commands were faster.

Another common scenario: a developer needs to deploy a configuration file to every web server. Alice copies a new httpd.conf file from her control node to the servers: ansible web-servers -m copy -a 'src=/home/alice/httpd.conf dest=/etc/httpd/conf/httpd.conf owner=root group=root mode=0644'. The copy module ensures the file is placed with the correct ownership and permissions. If the file already exists with the same content, Ansible does nothing — it is idempotent.

Alice also uses ad hoc commands for inventory management. She adds a new server to the [web-servers] group in her inventory file, then runs ansible all -m ping to verify all nodes are reachable. The ping module returns "pong" for each successful connection. This is her go-to test after any change to the inventory.

She uses the setup module to gather facts before a migration projec: ansible all -m setup -a 'filter=ansible_os_family'. This returns only the OS family of all nodes, helping her identify which servers run Red Hat versus Ubuntu. She uses that information to decide which package manager to use.

In production, Alice never uses the --ask-pass flag because passwords are insecure. She relies on SSH keys. She also uses --become with a dedicated automation user that has sudo privileges. She documents her most common ad hoc commands in a shared wiki so her team can reuse them.

When a critical vulnerability is announced, Alice can patch 150 servers in minutes: ansible all -m yum -a 'name=openssl state=latest' --become. She runs that, and Ansible updates the OpenSSL package across every server. She does not need to log in to each machine, type sudo yum update openssl, and manually confirm. One line, done.

How EX294 Actually Tests This

EX294 tests ad hoc commands heavily. Expect at least 3-5 questions on this topic. The exam presents scenarios and asks you to construct the correct ad hoc command from memory. You must know the exact syntax and module names.

Key exam topics:

The structure of an ad hoc command: ansible [host-pattern] -m [module] -a '[arguments]'.

The difference between command and shell modules. The exam will ask you to pick the right module for a task. If the task uses pipes (|), redirects (>), or environment variables ($HOME), the answer is shell. If it is a simple command without shell features, use command.

The module argument syntax. For the yum module, arguments are name=package_name state=latest. You must know that state=present ensures a package is installed but does not update it. state=latest ensures the most recent version.

The service module: arguments name=service_name state=started|stopped|restarted|reloaded enabled=yes|no.

The copy module: src=<local_path> dest=<remote_path> owner= user= group= mode=.

The file module: path= state=directory|file|absent owner= group= mode=.

The user module: name= state=present|absent uid= group= shell=.

The ping module: no arguments, just ansible all -m ping.

The setup module: no arguments required, but can filter with filter=ansible_*.

Traps in the exam:

They will give you a scenario where you need to use --become but the question does not mention "with elevated privileges." You must infer it. Any task that requires root, like installing packages or managing services, implicitly needs --become. If the answer choice includes --become and everything else is correct, it is likely correct.

They will test the difference between the raw module and command/shell. The raw module does not use the Ansible module system; it works over SSH without Python on the remote node. It is rarely needed and the exam may include it as a distractor.

They will ask about idempotence. If a question asks: "What happens if you run the same ad hoc command twice?" the correct answer is that the module will report "ok" and do nothing because the desired state is already met.

They will include the -a argument syntax with single quotes vs double quotes. The exam uses single quotes around the arguments string: -a 'name=httpd state=started'. Double quotes are also valid in some shells, but single quotes are safer and the exam uses them.

They will test the target pattern. If the inventory has a group [webservers], the target is webservers (no brackets). The keyword all targets every host in the inventory.

Key definitions to memorise:

Module: a pre-written, idempotent unit of code that performs a specific system management task.

Ad hoc command: a one-line Ansible command that runs a single module against one or more hosts.

Idempotence: property where running an operation multiple times produces the same result as running it once.

Control node: the machine where Ansible is installed and commands are executed.

Managed node: the remote system being configured by Ansible.

Key Takeaways

An ad hoc command starts with `ansible`, followed by a target pattern, `-m` for module, and `-a` for module arguments.

Use the `command` module for simple commands that do not need shell features like pipes, redirects, or environment variables.

Use the `shell` module only when you need shell-specific features; it is less secure than `command`.

The `yum` module arguments `name=package state=latest` install or update a package; `state=present` installs it but does not update an existing one.

The `service` module manages system services: `name=service state=started|stopped|restarted enabled=yes|no`.

Modules are idempotent: running the same ad hoc command multiple times leaves the system in the same desired state without making unintended changes.

Always use `--become` with tasks that require root privileges, such as installing packages or starting services.

The `ping` module tests SSH connectivity and Python availability on managed nodes, not ICMP ping.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

Ad Hoc Command

Run directly from the terminal, no file needed.

Best for single tasks like checking a service status.

Cannot use variables, loops, or conditionals easily.

Playbook

Written in a YAML file and executed with `ansible-playbook`.

Best for multi-step, repeatable automation tasks.

Supports variables, loops, conditionals, and error handling.

command Module

Does not use the shell, so pipes and redirects do not work.

Safer because it does not interpret shell metacharacters.

Quicker to execute as it uses direct system calls.

shell Module

Uses the shell, so pipes, redirects, and environment variables work.

Riskier as shell injection is possible if arguments are not sanitised.

Slower because it spawns a shell process on the managed node.

state=present (yum)

Ensures the package is installed but does not update it.

Will not upgrade a package that is already present.

Useful for ensuring a baseline version is installed.

state=latest (yum)

Ensures the most recent version of the package is installed.

Will upgrade the package if an older version is present.

Useful when you want the latest security patches.

SSH Keys

More secure because keys are stored on the control node.

Ad hoc commands can run without prompting for a password.

Standard for production automation.

Password Authentication

Passwords must be typed or passed with `--ask-pass`.

Passwords can be intercepted; not recommended for automation.

Used only in test environments or when keys are not set up.

Watch Out for These

Mistake

Ad hoc commands can only be run against a single host at a time.

Correct

Ad hoc commands can target multiple hosts, groups of hosts, or all hosts in the inventory using patterns like `all` or a group name.

Beginners often think Ansible is for individual machines like SSH. They do not realise `ansible all -m ping` runs on every host in the inventory.

Mistake

The `shell` module is always better than the `command` module because it does more.

Correct

The `command` module is safer and more predictable because it does not pass commands through the shell, avoiding shell injection and quoting issues. Use `shell` only when you need shell features like pipes.

New users see that `shell` works for everything and assume it is a superset. They miss that the exam explicitly tests the security trade-off.

Mistake

Modules run on the control node.

Correct

Modules are transferred to and executed on the managed node. Ansible pushes the module code (a Python script) to the remote machine, runs it, and collects the result.

This misconception comes from other tools that run centrally. Understanding where execution happens is crucial for designing secure automation.

Mistake

You always need to write a playbook; ad hoc commands are useless in production.

Correct

Ad hoc commands are essential for quick troubleshooting, one-off tasks, and verifying state across many servers. They are not a replacement for playbooks but a complementary tool.

Beginners often read that playbooks are the "real" automation and dismiss ad hoc commands as training wheels. In practice, sysadmins use ad hoc commands daily.

Mistake

The `setup` module is only for gathering facts, and you cannot use it in ad hoc commands.

Correct

You can run `ansible all -m setup` as an ad hoc command to quickly view facts from all managed nodes. It is a valid and useful ad hoc command.

Many learners treat `setup` as a playbook-only feature. But it is a module like any other and works with the `-m` flag.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

What is the difference between an ad hoc command and a playbook?

An ad hoc command runs one module immediately from the terminal. A playbook is a YAML file that can run multiple modules, include variables, conditionals, and loops. Use ad hoc commands for quick, one-time tasks and playbooks for repeatable, complex automation.

Do I need to install Ansible on every managed node?

No. Ansible only needs to be installed on the control node. It connects to managed nodes via SSH and runs modules directly on them without any agent software. However, the managed nodes must have Python 2.7 or Python 3 installed because modules are Python scripts.

Can I use ad hoc commands to copy files from managed nodes to my control node?

The `copy` module only copies files from the control node to managed nodes. To fetch files from managed nodes back to the control node, you must use the `fetch` module or a tool like `scp`. The `fetch` module is not commonly tested on EX294 for ad hoc commands, but you should know it exists.

What happens if I run an ad hoc command and the module does not exist?

Ansible will return an error stating the module was not found. You must use a module that is either built into Ansible (like the ones listed in this chapter) or installed as a collection. Built-in modules are always available. Check your module name spelling if you get this error.

How do I pass multiple arguments to a module?

Separate arguments with spaces inside the single-quoted string. For example: `ansible all -m yum -a 'name=httpd state=latest enablerepo=epel'`. Each key=value pair is separated by a space. Do not use commas or semicolons.

Can I run an ad hoc command as a different user?

Yes, use the `-u` flag followed by the username: `ansible all -m ping -u admin`. This tells Ansible to connect as `admin` instead of the current user. Combine with `--become` to escalate privileges after connecting as that user.

Terms Worth Knowing

Keep going

You've finished Ansible Modules and Ad Hoc Commands. Continue through the EX294 study guide to build a complete picture of the exam.

Done with this chapter?