# ansible / automation / ad-hoc

Execute Quick Tasks with Ad-Hoc Commands

An Ansible ad-hoc command is a powerful one-line command used to perform quick tasks on remote servers without the overhead of writing a full YAML playbook.

$ ansible all -m ping
server-01SUCCESS
server-02SUCCESS
server-03SUCCESS
-m
module flag
-a
argument flag
-b
become (sudo)
# overview

Why Use Ad-Hoc Commands?

Playbooks are designed for repeatable, complex automation. But sometimes, you just need to restart a service right now, or check the disk space across 50 servers instantly.

Perfect Use Cases

  • speed

    Fast Execution: You don't want to create and manage a YAML playbook for a single action.

  • diagnostics

    Quick Checks: Testing connectivity, verifying configurations, or gathering simple facts.

  • incident response

    Troubleshooting: Immediate actions like restarting a crashed service or clearing a full log directory.

  • disposable

    One-Time Tasks: Tasks that are temporary and don't need to be committed to version control.

# execution

System & Execution Operations

These are your bread-and-butter commands for checking inventory, verifying access, and running arbitrary shell commands across your fleet.

command vs shell

Module Differences

The command module is secure and predictable, but it does not process bash operators. If you need to use pipelines (|), redirects (>), or env variables, you must use the shell module instead.

terminal
# List all hosts mapped in your inventory file
$ ansible --list-hosts all
# Ping all servers to verify SSH connectivity
$ ansible -m ping all
# Ping a specific group (e.g., 'node' group)
$ ansible -m ping node
# Run a basic command to check disk space
$ ansible -m command -a "df -h" all
# Use the shell module to support pipelines (|)
$ ansible -m shell -a "df -h | grep /dev/sda1" all
# state

Packages, Services & Users

terminal
# Install Apache using apt (-b runs with sudo/elevated privileges)
$ ansible node -m apt -a "name=apache2 state=present update_cache=yes" -b
# Install multiple packages at once
$ ansible all -m apt -a "name='vim,git,curl' state=present update_cache=yes" -b
# Restart a service across all hosts
$ ansible all -m service -a "name=apache2 state=restarted" -b
# Create a new user and add them to the sudo group safely
$ ansible all -m user -a "name=devops state=present groups=sudo append=yes" -b

Key Parameters Explained

  • -b

    Become: Tells Ansible to execute the command with root/sudo privileges. Required for package installations and service restarts.

  • state=present

    Declarative State: Ensures the package or user exists. If it already does, Ansible does nothing.

  • append=yes

    Safe Group Addition: When adding a user to a group, this ensures they are not accidentally removed from their other existing groups.

# data

File Operations & Sync

Need to pull logs down from 50 servers at once? Or push a hotfix config file out to an entire cluster? Ad-hoc commands handle file operations flawlessly.

idempotency

State = Absent

In Ansible, you don't run a "delete" command. Instead, you use the file module and set the state to absent. Ansible will wipe the file or directory if it exists, and gracefully succeed if it's already gone.

terminal
# Create a directory with specific permissions
$ ansible all -m file -a "dest=/tmp/ak mode=644 state=directory"
# Delete a file or directory safely
$ ansible all -m file -a "path=/tmp/oldfile state=absent"
# Copy a file from the Control Node to Managed Nodes
$ ansible all -m copy -a "src=config dest=/tmp"
# Pull (fetch) a file from Managed Nodes to the Control Node
# flat=yes prevents Ansible from creating separate subdirectories per host
$ ansible all -m fetch -a "src=/etc/hosts dest=~/hosts_backup/ flat=yes"
# Sync entire directories (uses rsync under the hood)
$ ansible all -m synchronize -a "src=/local/dir dest=/remote/dir"
# notes

Lessons from running this in production

INFO

The template module can also be used ad-hoc (ansible -m template -a "src=temp dest=/tmp"), but templates usually rely on Jinja2 variables defined in playbooks, making them much more useful inside standard YAML files.

WARN

Because ad-hoc commands are typed directly into your terminal, they are saved in your shell's .bash_history. Never pass plaintext passwords or sensitive secrets via ad-hoc command arguments.

OK

Ad-hoc commands respect your inventory file completely. You can target all, a specific group like webservers, or even a single specific host by its hostname.