Ad-Hoc Commands¶
- In this lab we run Ansible ad-hoc commands to perform quick, one-off tasks on managed hosts without writing a playbook.
- Ad-hoc commands are perfect for gathering information, making quick changes, or testing connectivity.
- They use the same modules as playbooks, just invoked directly from the command line.
What will we learn?¶
- The syntax and structure of ad-hoc commands
- The most commonly used modules for ad-hoc tasks
- How to use
--becomefor privilege escalation - Practical use cases: fact gathering, file operations, service management
Prerequisites¶
- Complete the Lab 002 in order to have a working
Ansiblecontroller and inventory configuration.
01. Ad-Hoc Command Syntax¶
ansible <host-pattern> -m <module> -a "<arguments>" [options]
# Components:
# <host-pattern> : all, webservers, linux-server-1, etc.
# -m <module> : the module to run (default: command)
# -a "<arguments>": module arguments as key=value pairs
# [options] : --become, --user, --limit, -v, etc.
02. Essential Modules for Ad-Hoc Use¶
ping - Test Connectivity¶
# Ping all hosts
ansible all -m ping
# Ping a specific group
ansible webservers -m ping
# Ping with verbose output (shows SSH details)
ansible all -m ping -vvv
# In our demo lab:
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m ping"
### Output
linux-server-1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
command - Run a Command (No Shell Features)¶
# Run a command on all servers
ansible all -m command -a "uptime"
# Get the hostname
ansible all -m command -a "hostname"
# Check disk space
ansible all -m command -a "df -h"
# In our demo lab:
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m command -a 'uptime'"
NOTE: The
commandmodule does NOT use a shell - no pipes (|), redirects (>), or environment variables ($VAR). Use theshellmodule for those.
shell - Run Shell Commands¶
# Use shell features like pipes
ansible all -m shell -a "ps aux | grep nginx"
# Environment variable expansion
ansible all -m shell -a "echo $HOME"
# Multi-command with semicolons
ansible all -m shell -a "cd /tmp && ls -la"
# In our demo lab:
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m shell -a 'hostname'"
### Output
linux-server-3 | CHANGED | rc=0 >>
linux-server-3
linux-server-2 | CHANGED | rc=0 >>
linux-server-2
linux-server-1 | CHANGED | rc=0 >>
linux-server-1
raw - Run Commands Without Python¶
# Useful when Python is not installed on the target
ansible all -m raw -a "cat /etc/os-release"
# Bootstrap Python on a new node
ansible all -m raw -a "apt-get install -y python3"
03. File Operations¶
# Copy a file to all servers
ansible all -m copy -a "src=/tmp/test.txt dest=/tmp/test.txt"
# Create a file with content
ansible all -m copy -a "content='Hello from Ansible' dest=/tmp/hello.txt"
# Change file permissions
ansible all -m file -a "path=/tmp/hello.txt mode=0644 owner=root"
# Create a directory
ansible all -m file -a "path=/opt/myapp state=directory mode=0755"
# Delete a file
ansible all -m file -a "path=/tmp/hello.txt state=absent"
# Fetch a file from a remote host
ansible linux-server-1 -m fetch -a "src=/etc/hostname dest=/tmp/hostnames/"
04. Package Management¶
# Install a package (Debian/Ubuntu)
ansible all -m apt -a "name=curl state=present" --become
# Install multiple packages
ansible all -m apt -a "name=curl,wget,vim state=present update_cache=yes" --become
# Remove a package
ansible all -m apt -a "name=vim state=absent" --become
# Update all packages
ansible all -m apt -a "upgrade=dist" --become
# Use the generic package module (works on any OS)
ansible all -m package -a "name=curl state=present" --become
05. Service Management¶
# Start a service
ansible all -m service -a "name=nginx state=started" --become
# Stop a service
ansible all -m service -a "name=nginx state=stopped" --become
# Restart a service
ansible all -m service -a "name=nginx state=restarted" --become
# Enable service to start on boot
ansible all -m service -a "name=nginx enabled=yes" --become
# Use systemd module for more control
ansible all -m systemd -a "name=nginx state=started enabled=yes" --become
06. Gathering Facts¶
# Gather all facts about hosts
ansible all -m setup
# Filter facts by name pattern
ansible all -m setup -a "filter=ansible_distribution*"
ansible all -m setup -a "filter=ansible_memory_mb"
ansible all -m setup -a "filter=ansible_default_ipv4"
# Get all network interfaces
ansible all -m setup -a "filter=ansible_interfaces"
# Save facts to files
ansible all -m setup --tree /tmp/facts/
# In our demo lab:
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m setup -a 'filter=ansible_distribution*'"
07. User Management¶
# Create a user
ansible all -m user -a "name=john state=present" --become
# Add user to a group
ansible all -m user -a "name=john groups=sudo append=yes" --become
# Delete a user
ansible all -m user -a "name=john state=absent remove=yes" --become
08. Useful Options¶
| Option | Description |
|---|---|
-b / --become | Enable privilege escalation (sudo) |
--become-user | Become a specific user (default: root) |
-K | Prompt for sudo password |
-u <user> | Connect as this SSH user |
--limit <pattern> | Limit to a subset of hosts |
-f <N> | Number of parallel forks (default: 5) |
-v / -vv / -vvv | Increase verbosity |
--check | Dry run - show what would change without changing it |
--diff | Show diff of changes |

09. Hands-on¶
- Test connectivity to all hosts using the
pingmodule.
??? success “Solution”
- Get the uptime of all servers using the
commandmodule.
??? success “Solution”
- Create a file
/tmp/ansible-test.txton all servers with the contentCreated by Ansible ad-hoc, then verify it exists, then remove it.
??? success “Solution”
# Create the file
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m copy -a \"content='Created by Ansible ad-hoc' dest=/tmp/ansible-test.txt\""
# Verify
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m command -a 'cat /tmp/ansible-test.txt'"
# Remove
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m file -a 'path=/tmp/ansible-test.txt state=absent'"
- Gather OS distribution facts from all hosts.
??? success “Solution”
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m setup -a 'filter=ansible_distribution*'"
- Get memory information from all hosts.
??? success “Solution”
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m setup -a 'filter=ansible_memtotal_mb'"
- Install
curlon all servers, then verify the installation.
??? success “Solution”
# Install
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m apt -a 'name=curl state=present' --become"
# Verify
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m command -a 'curl --version'"
- Use a shell command with a pipe to list all running processes that contain the word
python.
??? success “Solution”
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m shell -a 'ps aux | grep python'"
- Create a directory
/tmp/ad-hoc-demoon all servers, then remove it.
??? success “Solution”
# Create
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m file -a 'path=/tmp/ad-hoc-demo state=directory mode=0755'"
# Remove
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m file -a 'path=/tmp/ad-hoc-demo state=absent'"
10. Summary¶
- Ad-hoc commands use the syntax:
ansible <hosts> -m <module> -a "<args>" - The
commandmodule is safe but limited - no pipes or shell expansion - Use
shellwhen you need pipes (|), redirects (>), or environment variables setupgathers system facts; usefilter=to narrow results--becomeelevates privileges (sudo) for tasks that require it- Ad-hoc commands are ideal for quick one-off tasks; use playbooks for anything repeatable
- Common modules:
ping,command,shell,copy,file,apt,service,setup