What is an Ad-Hoc Command?
You don't always need to write a full YAML playbook to use Ansible. Sometimes, you just need to do one simple thing across 50 servers immediately.
For example:
- "Are all my servers online?"
- "What is the uptime of my database cluster?"
- "Reboot all web servers right now."
Ad-Hoc commands allow you to execute a single Ansible module directly from the command line. They are fast, powerful, and excellent for troubleshooting or one-off administrative tasks.
Anatomy of an Ad-Hoc Command
Every ad-hoc command follows a standard syntax:
ansible [target] -i [inventory] -m [module] -a "[module_arguments]" --becomeThe Components Explained:
[target]: Which hosts or groups from your inventory do you want to run this against? (e.g.,all,webservers,192.168.1.10)-i [inventory]: The path to your inventory file. (Optional if defined inansible.cfg)-m [module]: The name of the Ansible module you want to use. (If omitted, Ansible defaults to thecommandmodule).-a "[module_arguments]": The arguments required by the module.--become: Tells Ansible to use privilege escalation (run assudo).
The Ping Module: Your First Command
The ping module is the ultimate connectivity test. Unlike the standard network ping command (which tests ICMP), Ansible's ping module actually logs into the target machine via SSH, locates Python, executes a simple script, and returns pong.
If an Ansible ping works, you know your credentials, SSH keys, and Python environment are all perfectly configured.
# Ping all servers in the inventory
ansible all -i inventory.ini -m pingExpected Output:
192.168.1.10 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}The Command and Shell Modules
If you want to run standard Linux terminal commands across your fleet, you use the command or shell modules.
The command module is the default, so you don't even need to type -m command.
Checking Uptime
ansible webservers -i inventory.ini -a "uptime"Output:
web1.example.com | CHANGED | rc=0 >>
14:32:01 up 14 days, 3:12, 1 user, load average: 0.04, 0.05, 0.01
web2.example.com | CHANGED | rc=0 >>
14:32:02 up 14 days, 3:15, 1 user, load average: 0.12, 0.08, 0.02Checking Free Memory
ansible databases -i inventory.ini -a "free -m"command vs shell
The command module runs a command safely by avoiding the shell environment. This means pipes (|), redirects (>), and environment variables ($HOME) will not work.
If you need bash piping, you must use the shell module:
# This will FAIL (using command module by default)
ansible all -i inventory.ini -a "cat /var/log/syslog | grep error"
# This will WORK (specifying the shell module)
ansible all -i inventory.ini -m shell -a "cat /var/log/syslog | grep error"System Administration Tasks
Ad-Hoc commands shine when you need to perform rapid system administration.
Remember: Whenever you perform an action that requires sudo (like installing packages or restarting services), you must append the --become flag (-b for short) to your command.
Managing Packages (APT/YUM)
Ensure the htop package is installed and at the latest version across all servers:
# For Ubuntu/Debian servers
ansible all -i inventory.ini -m apt -a "name=htop state=latest" --become
# For CentOS/RHEL servers
ansible all -i inventory.ini -m dnf -a "name=htop state=latest" --becomeManaging Services
Restart the Nginx service on all web servers:
ansible webservers -i inventory.ini -m service -a "name=nginx state=restarted" --becomeEnsure a service is stopped immediately:
ansible webservers -i inventory.ini -m service -a "name=apache2 state=stopped" --becomeManaging Files
Copy a file from your laptop to 50 target servers:
ansible all -i inventory.ini -m copy -a "src=/local/path/config.txt dest=/etc/config.txt owner=root mode=0644" --becomeRebooting Servers
Safely reboot all database servers:
ansible databases -i inventory.ini -m reboot --becomeLimitations of Ad-Hoc Commands
Ad-hoc commands are fantastic for fast operations, but they have major drawbacks:
- Not Version Controlled: You execute them in a terminal, and they are lost to history. Your team doesn't know what you ran.
- Hard to read: Cramming 10 arguments into a single terminal string (
-a "name=htop state=latest update_cache=yes") gets messy quickly. - No logic: You cannot execute conditional statements ("If the OS is Ubuntu, do X, else do Y") or loops.
For permanent, repeatable, and complex infrastructure automation, we abandon ad-hoc commands and graduate to Playbooks.