Mastering Essential Ad-Hoc Commands for Quick Ansible Tasks

Use Ansible ad-hoc commands for quick checks, one-off fixes, file changes, and fact gathering without writing a playbook.

Mastering Essential Ad-Hoc Commands for Quick Ansible Tasks

Ansible ad-hoc commands let you run one quick task across one host or a whole group. They are useful when you need to test access, check disk space, copy a file, restart a service, or inspect facts without writing a playbook first.

They are not a replacement for playbooks. Use them for immediate work, then move repeated or risky tasks into version-controlled automation.

Basic Command Structure

An ad-hoc command follows this shape:

ansible <pattern> -m <module_name> -a "<module_arguments>" [options]

The host pattern selects inventory targets. The module decides what Ansible does. The arguments pass module-specific values.

Common options include:

  • -i <inventory> or --inventory <inventory>: use a specific inventory file or inventory source.
  • -u <user> or --user <user>: connect as a specific remote user.
  • -b or --become: use privilege escalation, usually sudo.
  • -k or --ask-pass: ask for the SSH password.
  • -K or --ask-become-pass: ask for the sudo password.
  • --limit <subset>: narrow the selected hosts further.

If you do not pass -i, Ansible uses its configured inventory. On many systems that is /etc/ansible/hosts, but your ansible.cfg can change it.

Test Access with ping

The ping module does not send ICMP echo packets. It connects through Ansible's normal transport, runs a small module on the target, and expects pong back.

ansible all -m ping

For one group:

ansible webservers -m ping

A successful result looks like this:

web01.example.com | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

If this fails, fix inventory, DNS, SSH keys, remote user, sudo settings, or Python availability before troubleshooting higher-level tasks.

Run Simple Commands with command

The command module runs a program directly on the remote host. It does not invoke a shell, so pipes, redirects, glob expansion, and $VARIABLE expansion do not work the way they would in your terminal.

Check uptime:

ansible webservers -m command -a "uptime"

Check disk usage:

ansible all -m command -a "df -h"

List a protected directory with sudo:

ansible dbservers -m command -a "ls -l /var/log" --become

Use command first when you do not need shell features. It is easier to reason about and avoids accidental shell interpretation.

Use shell Only When You Need Shell Features

The shell module runs the command through a shell on the remote host. Use it for pipes, redirects, variable expansion, and shell conditionals.

Find the largest log directories:

ansible databases -m shell -a "du -sh /var/log/* | sort -rh | head -n 5"

Check a remote environment variable:

ansible all -m shell -a "printf '%s\n' \"$PATH\""

Be careful with dynamic input. If user-provided values are inserted into a shell command without quoting and validation, you can create a command injection bug.

For file edits, prefer a purpose-built module instead of shell redirection. For example, add a managed line with lineinfile:

ansible webservers -m lineinfile -a "path=/etc/app/app.conf line='feature_enabled=true' create=yes" --become

That is safer and more repeatable than appending with echo ... >> file.

Copy Files with copy

The copy module transfers files from your control node to managed hosts.

ansible webservers -m copy -a "src=./myscript.sh dest=/tmp/myscript.sh mode=0755"

Copy a config file that requires root ownership:

ansible all -m copy -a "src=./app.conf dest=/etc/app/app.conf owner=root group=root mode=0644" --become

If the destination already has the same content and metadata, Ansible reports no change.

Manage Paths with file

Use the file module to create directories, remove paths, set ownership, set permissions, or create symlinks.

Create a directory:

ansible appservers -m file -a "path=/opt/my_app state=directory mode=0755 owner=app group=app" --become

Remove an old file:

ansible host1 -m file -a "path=/tmp/old_file.txt state=absent"

Create a symlink:

ansible appservers -m file -a "src=/opt/my_app/releases/current dest=/opt/my_app/current state=link"

Gather Facts with setup

The setup module collects facts about a host, including OS, network, CPU, memory, and device details.

Gather all facts from one host:

ansible webserver1 -m setup

Filter facts when you only need a small slice:

ansible all -m setup -a "filter=ansible_distribution*"

The output can be large, so filtering keeps troubleshooting readable.

Pick Ad-Hoc Commands or Playbooks

Use ad-hoc commands for quick checks and one-off tasks:

  • Test connectivity with ping.
  • Check state with command.
  • Copy one known file with copy.
  • Create or remove one path with file.
  • Gather facts during troubleshooting.

Use playbooks when the task is repeated, multi-step, reviewed by teammates, or risky enough that you want version control and predictable structure.

Safety Checks Before You Run

Check the host pattern before running anything destructive:

ansible webservers --list-hosts

Use --limit when you want a smaller blast radius:

ansible all --limit web01.example.com -m ping

Remember that command and shell are not automatically idempotent. A command like useradd deploy may fail on the second run unless you write it defensively. Modules such as user, file, copy, and lineinfile usually give you safer repeat behavior.

Takeaway

Ansible ad-hoc commands are best for fast, targeted operations. Start with ping, use command for simple checks, reserve shell for real shell syntax, and prefer modules like copy, file, lineinfile, and setup when they match the job.