Ansible - Ad-Hoc Commands

Ansible
SSH
Published

August 9, 2018

Modified

April 10, 2024

Introduction to ad hoc commands

ansible [pattern] -m [module] -a "[module options]"

Privilege Escalation

…execute tasks with root (or another user) …read understanding privilege escalation

Options…

  • -b, --become …activate privilege escalation
  • -k, --ask-pass …ask for connection password
  • -K, --ask-become-pass …both the above
  • …user configuration…
    • --become-user=$USER …defaults to root
    • …defaults to --become-method=sudo …other choices su, doas, etc

Command & Shell

ansible.builtin.command …run an arbitrary command…

  • …will not be processed through the shell
  • …redirection like | will not work
  • …option -o folds the output to a single line per node
>>> ansible -m ansible.builtin.command -a 'echo $SHELL' alpha
alpha | CHANGED | rc=0 >>
/bin/bash

# ...for example to check the kernel version
>>> ansible -o -a 'uname -r' alpha
alpha | CHANGED | rc=0 | (stdout) 4.18.0-477.10.1.el8_8.x86_64

ansible.builtin.shell executes a command in a shell environment

  • …supports wild-cards and redirection
  • Common parameters…
    • executable= …path to the shell interpreter
    • chdir= …absolute path to the working directory
# ...support piping ...for example
ansible -m shell -a 'cat /var/log/messages | grep ansible | wc -l' #...

# ...use ZSH interpreter
ansbile -m shell -a "executable=/bin/zsh echo $SHELL" #...

Setup

ansible.builtin.setup gathers facts about remote hosts…

>>> ansible -m setup alpha | head
alpha | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.121.9",
            "192.168.18.10"
        ],
#...

The filter parameter returns facts that match one of the shell-style pattern…

# ...for example state of memory allocation
ansible -m setup -a 'filter=ansible_*_mb' ...

gahter_subset restrict the additional facts collected to the given subset…

  • …list in the documentation for gather_subset parameter
  • …sets values separated by comma …example kernel,machine
  • …negation with ! …example !hardware,!network
# ...collected a given subset only
ansible -m setup -a 'gather_subset=network'

# ...display facts from all hosts and store them indexed by hostname at /tmp/facts
ansible -m ansible.builtin.gather_facts --tree /tmp/facts #...

Files & Directories

ansible.builtin.file …manipulate files, directories, or symlinks

  • path= …absolute path to file
  • States…
    • state=file …current state of path …state=touch creates an empty file
    • state=directory …aka mkdir -p
    • state=link …symbolic link will be created changed …state=hard for hard link
    • state=absent …delete file …recursive delete for directories …does not file if path missing
  • Permissions…
    • mode=chmod permissions
    • group=chown own the filesystem object …defaults to current user unless you are root
    • owner= … user that should own the filesystem object …defaults to current user unless you are root
# ...remove a path
ansbile -m file -a 'path=<path> state=absent'

# ...set permissions to a path
ansible -m file -a 'path=<path> mode=<mode> owner=<user> group=<group>'

# ...create a symbolic link
ansible -m file -a 'state=link path=<path> src=<path>'

ansible.builtin.copy & ansible.builtin.fetch …copy files between target and localhost

# ...copy file from localhost to target
ansible -m copy -a 'src=<path> dest=<path>'

# ...copy file from target to localhost
ansible -m fetch -a 'src=<path> dest=<path>'

ansible.posix.synchronize …wrapper around rsync

ansible.builtin.get_url …downloads files from HTTP, HTTPS, or FTP

  • …respects *_proxy environment variables on the target
  • url= …format (http|https|ftp)://[user[:pass]]@host.domain[:port]/path
  • dest= …absolute path to destination file
  • mode=chmod permissions
  • backup=true …create backup file including timestamp
ansible -m get_url -a "url=<url> dest=<path> mode=<mode>"

ansible.builtin.replace …replace all instances of a particular string in a file

ansible -m replace -a "dest=<path> regexp=<regex> backup=yes"

Services

ansible.builtin.service controls services…

  • state= …at least one of state required
    • started/stopped …idempotent …run when necessary
    • restarted …always bounce the service
    • reload …will start the service if not started
  • enabled=yes …service should start on boot
ansible -m service -a 'name=chronyd state=started' #...

Packages

ansible.builtin.dnf installs, upgrade, removes, and lists packages and groups

# ...install a packages
ansible -m dnf -a 'state=installed name=httpd,nginx'
ansible -m dnf -a 'state=installed name=@development'
# ...in a specific version
ansible -m dnf -a "state=installed name='httpd >= 2.4'"

# ...remove a package
ansible -m dnf -a 'state=removed name=vim'

Common parameters…

  • update_cache=true check if cache is out of date …redownload if needed
  • update_only=true state=latest …only update installed packages …do not install packages

Asynchronous Tasks

Asynchronous ad hoc tasks

  • …long-running process to execute in the background
  • …option -B timeout in seconds
  • …option -P 0 to disable polling
    • …otherwise the connection would stay open
    • …task runs until it either completes, fails or times out
  • …return a job ID unique to each target
    • …used with the async_status module
    • jid= parameter to identify a specific task
# ...start a long running command
>>> ansible -B 3600 -P 0 -a 'dnf -y update' #...
alpha | CHANGED => {
#...
    "ansible_job_id": "j972636535559.11608",
#...
    "results_file": "/root/.ansible_async/j972636535559.11608",
#...

# ...check the status if a long running command
>>> ansible -m async_status -a jid=j972636535559.11608 #...
alpha | SUCCESS => {
#...
    "ansible_job_id": "j972636535559.11608",
    "changed": false,
    "finished": 0,
#...


# ...after the task has finished
>>> ansible -m async_status -a jid=j972636535559.11608 #...
alpha | CHANGED => {
#...
    "ansible_job_id": "j972636535559.11608",
    "changed": true,
    "cmd": [
        "dnf",
        "-y",
        "update"
    ],
    "delta": "0:09:17.975386",
    "end": "2023-08-08 08:54:00.427203",
    "finished": 1,
#...