G
GuideDevOps
Lesson 4 of 14

Ad-Hoc Commands

Part of the Ansible tutorial series.

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]" --become

The Components Explained:

  1. [target]: Which hosts or groups from your inventory do you want to run this against? (e.g., all, webservers, 192.168.1.10)
  2. -i [inventory]: The path to your inventory file. (Optional if defined in ansible.cfg)
  3. -m [module]: The name of the Ansible module you want to use. (If omitted, Ansible defaults to the command module).
  4. -a "[module_arguments]": The arguments required by the module.
  5. --become: Tells Ansible to use privilege escalation (run as sudo).

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 ping

Expected 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.02

Checking 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" --become

Managing Services

Restart the Nginx service on all web servers:

ansible webservers -i inventory.ini -m service -a "name=nginx state=restarted" --become

Ensure a service is stopped immediately:

ansible webservers -i inventory.ini -m service -a "name=apache2 state=stopped" --become

Managing 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" --become

Rebooting Servers

Safely reboot all database servers:

ansible databases -i inventory.ini -m reboot --become

Limitations of Ad-Hoc Commands

Ad-hoc commands are fantastic for fast operations, but they have major drawbacks:

  1. Not Version Controlled: You execute them in a terminal, and they are lost to history. Your team doesn't know what you ran.
  2. Hard to read: Cramming 10 arguments into a single terminal string (-a "name=htop state=latest update_cache=yes") gets messy quickly.
  3. 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.