A complete guide to Ansible Ad hoc Commands

A complete guide to Ansible Ad hoc Commands

·

14 min read

Play this article

In this article with a handful of examples I will demonstrate the power of Ansible's ad hoc commands which can be used to do a lot of stuff with just a single command on remote servers.

Prerequisites

  1. One Ansible Control Node The Ansible control or mater node will be the machine we will use to connect to and control the Ansible hosts over SSH.

  2. One or more Linux client nodes

    The Ansible control node will be performing configuration management tasks on Linux client nodes.

  3. SSH connection SSH connection should be enabled between Ansible control node and the remote client servers. Assuming either the Ansible control node’s SSH public key added to the authorized_keys of a system user or use the root or sudo user's password to connect.

My Environment

HostnameIP addressOperating System
lco-ansible-master.example.com172.52.52.200CentOS Linux 7 (Core)
lco-worker1.example.com172.52.52.201CentOS Linux 7 (Core)
lco-worker2.example.com172.52.52.202CentOS Linux 7 (Core)

Need of Ansible Ad hoc commands

Ad hoc commands are used to automate a single task on one or more client nodes. They are used to perform quick functions but are not repeatable.

For example if you want to power off a set of machines or if you want to make a service down on some hosts within your cluster you can use Ansible ad hoc commands and do that pretty quickly.

Test the connection

Before I start demonstrating the ad hoc commands example let us fist test our connection with Ansible client nodes.

My inventory file:

[ansible_user@lco-ansible-master ansible]$ cat myinventory
master ansible_host=lco-ansible-master.example.com ansible_user=ansible_user ansible_ssh_port=22
worker1 ansible_host=lco-worker1.example.com ansible_user=ansible_user ansible_ssh_port=22
worker2 ansible_host=lco-worker2.example.com ansible_user=ansible_user ansible_ssh_port=22

[master]
master

[workers]
worker1
worker2

Here we are using ansible_user which has sudo privileges to perform the administrative tasks on client nodes.

We can use ansible_ssh_private_key_file variable within inventory file if we wish to chose the custom private key file.

For example: master ansible_host=lco-ansible-master.example.com ansible_user=ansible_user ansible_ssh_port=22 ansible_ssh_private_key_file=/home/ansible_user/.ssh/custom_id_file

Test the connection:

[ansible_user@lco-ansible-master ansible]$ ansible -m ping all -i myinventory
[WARNING]: Found both group and host with same name: master
master | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
worker1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
worker2 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

Great! we are all set to perform some brilliant and quick stuff on our client nodes.

Ansible Ad hoc command examples

In this section we will take different examples of Ansible ad hoc commands to perform various things on remote servers.

Reboot client nodes

Many tasks on a Linux server including rebooting the servers requires higher privileges. For that we need to use --become keyword and enter the sudo user password in order to become root. If you add --ask-become-pass or -K, Ansible prompts you for the password to use for privilege escalation.

The default module for Ansible command line is command module. we can specify module names by using -m parameter.

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -a "/sbin/reboot" --become -K

The above command will prompt for the sudo user password, once entered correctly will reboot the worker1 node.

You can verify the reboot operation by going to the remote host and run the following command:

[ansible_user@lco-worker1 ~]$ last | grep -i reboot | head -2
reboot   system boot  3.10.0-1160.6.1. Sun Jan  3 14:06 - 14:07  (00:01)
reboot   system boot  3.10.0-1160.6.1. Sun Jan  3 14:02 - 14:06  (00:03)

Package Management

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m yum -a "name=vsftpd state=present" --become -K

The above command will install the vsftpd package on both the worker nodes. We are using the yum module to install the required package.

I order to remove a package use state=absent as argument.

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m yum -a "name=vsftpd state=absent" --become -K

On Debian based distributions for example on Ubuntu etc. we will use apt module for package management.

File Operations

In this section we will do perform some file operations on remote hosts.

Change File Permissions

We will use file module to perform file related operations on client nodes.

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m file -a "dest=/tmp/test.txt mode=600 owner=ansible_user group=ansible_user" --become  -K

Here we have adjusted file permissions on a file named test.txt which is present at /tmp on worker nodes.

We have set 600 permissions (giving read and write permissions to the owner) on the file using mode argument. mode defines the permissions the resulting file or directory should have. We have also set the ownership and group membership of the file to ansible_user using owner and group arguments.

Copy files across the remote nodes

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m copy -a "src=./test_copy dest=/tmp/test_copy"

Verify the file presence on worker nodes:

[root@lco-worker1 tmp]# ls -l test_copy
-rw-rw-r--. 1 ansible_user ansible_user 0 Jan  3 14:34 test_copy

Here we have copied a local file named test_copy from Ansible control node over to worker nodes using copy module.

To copy remote server files over control node run following command: We use the fetch module in case we want to move files from the remote host to the local host (i.e. fetch a file from the remote host).

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m fetch -a "src=/tmp/test_copy_from_worker1 remote_src=yes dest=/tmp"

Verify the file presence on Ansible control node:

[ansible_user@lco-ansible-master ansible]$ ls -l /tmp/worker1/tmp/test_copy_from_worker1
-rw-rw-r--. 1 ansible_user ansible_user 0 Jan  3 14:54 /tmp/worker1/tmp/test_copy_from_worker1

It creates a directory structure for fetched files.

Create files and directories

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m file -a "path=/tmp/test_file

Above command will create a file named test_file under /tmp directory.

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m file -a "path=/tmp/test_dir state=directory"

Above command will create a directory named test_dir under /tmp directory.

You can get all the details about any file or directory by running following command:

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m file -a "path=/tmp/test_file"
worker1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "gid": 1001,
    "group": "ansible_user",
    "mode": "0664",
    "owner": "ansible_user",
    "path": "/tmp/test_file",
    "secontext": "unconfined_u:object_r:user_tmp_t:s0",
    "size": 0,
    "state": "file",
    "uid": 1001
}

Service Management

We use Ansible's service module to perform service related tasks.

Start a service

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m service -a "name=vsftpd state=started" --become -K

Restart a service

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m service -a "name=vsftpd state=restarted" --become -K

Stop a service

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m service -a "name=vsftpd state=stopped" --become -K

System Information (facts ) gathering

Ansible facts are data related to your remote systems, including operating systems, IP addresses, attached filesystems, and more. By using Ansible's setup module we can gather remote systems facts variables.

Gather all the facts about a system

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m setup

Filter gathering facts

We get a lot of data as an output of setup command we ran above but we can always filter the facts output as we require.

For example if we want to know the Python version running on remote host run the following command:

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m setup -a 'filter=ansible_python_version'

worker1 | SUCCESS => {
    "ansible_facts": {
        "ansible_python_version": "2.7.5",
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false
}

Find the OS family:

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m setup -a 'filter=ansible_os_family'
worker1 | SUCCESS => {
    "ansible_facts": {
        "ansible_os_family": "RedHat",
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false
}

Find all the details about an network interface:

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m setup -a 'filter=ansible_eth1'

Find memory details on a host:

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m setup -a 'filter=ansible_memory_mb'
worker1 | SUCCESS => {
    "ansible_facts": {
        "ansible_memory_mb": {
            "nocache": {
                "free": 1633,
                "used": 204
            },
            "real": {
                "free": 1278,
                "total": 1837,
                "used": 559
            },
            "swap": {
                "cached": 0,
                "free": 2047,
                "total": 2047,
                "used": 0
            }
        },
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false
}

User Management

We use Ansible's user module to perform user management tasks.

Create a user

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m user -a "name=test" --become -K

Add user to a group

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m user -a "name=test append=yes group=wheel" --become -K

Here we are adding user test to wheel group. If you notice we've used append flag and set it to yes because if not set to yesit will wipe out the details of previous groups for that user.

Remove a user

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m user -a "name=test state=absent" --become -K

To remove a user, we use state flag and set it to absent as above.

Find Disk Usage on remote host

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -a "df -hT"
worker1 | CHANGED | rc=0 >>
Filesystem              Type      Size  Used Avail Use% Mounted on
devtmpfs                devtmpfs  908M     0  908M   0% /dev
tmpfs                   tmpfs     919M     0  919M   0% /dev/shm
/dev/mapper/centos-root xfs        41G  1.6G   40G   4% /
/dev/sda1               xfs      1014M  253M  762M  25% /boot
/dev/mapper/centos-home xfs        20G   33M   20G   1% /home

Find high CPU consuming processes

The following command will list down the processes with higher cpu consumption.

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m shell -a "ps -eo pid,ppid,%mem,%cpu,cmd --sort=-%cpu | head"

Here we have used Ansible's shell module.

To know about the highest cpu consuming processes you can use top command as well.

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m shell -a "top -c -b | head -15"

Ansible command module does not support the pipe character and does not support redirection

Find high Memory consuming processes

The following command will list down the processes with higher memory consumption.

[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m shell -a "ps -eo pid,ppid,%mem,%cpu,cmd --sort=-%mem | head"

That's all for this article but surely we can achieve a lot more things with Ansible Ad Hoc commands.

Hope you like the article. Stay Tuned for more.

Thank you. Happy learning!

Did you find this article valuable?

Support Learn Code Online by becoming a sponsor. Any amount is appreciated!