Ansible Ad Hoc Commands — Run Tasks Without Playbooks
Introduction
Ad hoc commands let you run single Ansible tasks from the command line without writing a playbook. They're perfect for quick checks, one-off changes, and troubleshooting. Think of them as the ssh command on steroids — run any module against any number of hosts in parallel.
Syntax
ansible <pattern> -m <module> -a "<arguments>" [options]
Component
Description
pattern
Host or group to target (all, webservers, db01)
-m
Module name (default: command)
-a
Module arguments
-i
Inventory file
-b
Become (sudo)
-u
Remote user
-k
Ask for SSH password
-K
Ask for become password
--limit
Further limit hosts
-f
Forks (parallelism, default: 5)
-o
One-line condensed output
--check
Dry run
Connectivity Check
# Ping all hosts
ansible all -m ping
# Ping a specific group
ansible webservers -m ping
# Ping a single host
ansible db01 -m ping -i inventory.yml
# Ping with SSH password prompt
ansible all -m ping -k
Run Shell Commands
# Default module is 'command' (no shell features)
ansible all -a "uptime"
ansible all -a "df -h"
ansible all -a "free -m"
# Use 'shell' module for pipes, redirects, env vars
ansible all -m shell -a "ps aux | grep nginx | wc -l"
ansible all -m shell -a "echo $HOSTNAME"
ansible all -m shell -a "cat /etc/os-release | head -3"
# Run as root
ansible all -m shell -a "cat /etc/shadow | head -1" -b
File Operations
# Copy a file to remote hosts
ansible all -m copy -a "src=/tmp/config.txt dest=/etc/app/config.txt" -b
# Create a directory
ansible all -m file -a "path=/opt/myapp state=directory mode=0755" -b
# Delete a file
ansible all -m file -a "path=/tmp/junk.log state=absent"
# Change ownership
ansible all -m file -a "path=/var/www owner=www-data group=www-data recurse=yes" -b
# Fetch a file from remote
ansible db01 -m fetch -a "src=/var/log/syslog dest=/tmp/logs/"
Package Management
# Install a package (Debian/Ubuntu)
ansible webservers -m apt -a "name=nginx state=present update_cache=yes" -b
# Install a package (RHEL/CentOS)
ansible webservers -m yum -a "name=httpd state=present" -b
# Install on any distro
ansible all -m package -a "name=curl state=present" -b
# Remove a package
ansible all -m apt -a "name=telnet state=absent" -b
# Upgrade all packages
ansible all -m apt -a "upgrade=dist" -b
Service Management
# Start a service
ansible webservers -m service -a "name=nginx state=started" -b
# Restart a service
ansible webservers -m service -a "name=nginx state=restarted" -b
# Enable a service at boot
ansible webservers -m service -a "name=nginx enabled=yes" -b
# Stop a service
ansible webservers -m service -a "name=nginx state=stopped" -b
User Management
# Create a user
ansible all -m user -a "name=deploy state=present shell=/bin/bash" -b
# Create user with SSH key
ansible all -m user -a "name=deploy generate_ssh_key=yes" -b
# Remove a user
ansible all -m user -a "name=olduser state=absent remove=yes" -b
# Add user to groups
ansible all -m user -a "name=deploy groups=sudo,docker append=yes" -b
Gathering Facts
# Get all facts
ansible db01 -m setup
# Filter specific facts
ansible db01 -m setup -a "filter=ansible_distribution*"
ansible db01 -m setup -a "filter=ansible_memtotal_mb"
ansible db01 -m setup -a "filter=ansible_default_ipv4"
Parallelism and Limiting
# Run on 10 hosts at a time
ansible all -a "uptime" -f 10
# Limit to specific hosts
ansible webservers -a "uptime" --limit "web01,web02"
# Limit with pattern
ansible all -a "uptime" --limit "*.example.com"
# One host at a time (serial)
ansible all -a "systemctl restart nginx" -b -f 1
Output Formats
# One-line condensed output
ansible all -a "uptime" -o
# Verbose output
ansible all -m ping -v
ansible all -m ping -vvv # Very verbose (connection debugging)
# JSON output (for scripting)
ANSIBLE_STDOUT_CALLBACK=json ansible all -m ping
Dry Run and Diff
# Check mode (dry run)
ansible all -m apt -a "name=nginx state=present" -b --check
# Diff mode (show changes)
ansible all -m copy -a "src=config.txt dest=/etc/app/config.txt" -b --diff
# Both together
ansible all -m copy -a "src=config.txt dest=/etc/app/config.txt" -b --check --diff
Common Patterns
# Reboot all servers (one at a time)
ansible all -m reboot -b -f 1
# Check disk space and alert
ansible all -m shell -a "df -h / | tail -1" -o
# Kill a process
ansible webservers -m shell -a "pkill -f 'stuck_process'" -b
# Test connectivity and latency
ansible all -m shell -a "ping -c 1 google.com | tail -1"
# Distribute SSH keys
ansible all -m authorized_key -a "user=deploy key='{{ lookup('file', '~/.ssh/id_rsa.pub') }}'" -b
# Update /etc/hosts
ansible all -m lineinfile -a "path=/etc/hosts line='192.168.1.100 app.local'" -b
Ad hoc commands are your Swiss Army knife for quick Ansible tasks. Use them for troubleshooting, one-off changes, and exploring your infrastructure. For anything repeatable, graduate to playbooks — but keep ad hoc commands in your toolbox for when you need fast results.