Ansible Command Module Examples

By Linux Guru 01.01.0001

Excerpt

Ansible Command module is used to execute commands on a remote node.

The Command module is mainly used to execute simple Linux commands on a remote node/server that is part of a server group or a standalone server mentioned in the server group.

If you want to run some simple shell commands on a remote server, you can use


Ansible Command Module Examples

The Ansible Command module is used to execute commands on the remote node.

The Command module is mainly used to execute simple Linux commands on a remote node/server that is part of a server group or a standalone server mentioned in the server group.

If you want to run some simple shell commands on a remote server, you can use this Ansible command module

.ansibleimage

But when there are no overly complicated shell commands or two commands concatenated with PIPE. you cannot use this command module and you must choose the shell module instead of this one.

Not just a pipe, if you use one of these characters like | > < in your command you should consider using the shell module

Where to use Ansible SHELL and Where to use Ansible COMMAND?

ls -lrt /etc/httpd/conf  is simple and can be executed with Ansible command module

ls -lrt /etc/httpd/conf|awk '{print $9}'  It has PIPE simple in it. you should use Shell module for this command

If you think the Ansible Shell module is what you want. Refer the following article or If you would like to continue with Ansible Command module Continue to read.

Prerequisites

We assume you have Ansible and a few virtual machines to test it on and we strongly recommend Administrator instead of traditional virtual machines like Oracle Virtual Box/VMware WorkStation etc.

We designed this article specifically for the command module.

If you want to know, learn the basics like what is Ansible, what is an Administrator, and how to install, configure them, and create your local workspace.

  • Get remote server availability with ansible command module
  • Get server name and version using UNAME
  • Check the disk usage of a remote server or node using the Ansible command module.
  • Restart Apache on the remote server using the ansible command module
  • Execute command when file exists or does not exist (yes or no) [ Create a file if it does not exist, Delete a file if it is present or exists ]
  • Run script only if a certain file is present (or) absent (EXIST or NOT EXIST)

Here I have two Virtual machines named wmiweb002 and wmivmapp001 grouped in the name of testservers in an ansible_hosts file. Let us quickly list the servers under the host group testservers.

$ ansible testservers --list -i ansible_hosts
  hosts (2):
    wmiweb002
    wmivmapp001

Now you can see we have listed the machines/remote servers in the hostgroup named testservers.

Example 01: Get the Uptime of  remote servers

We have used command module to run the uptime command and we have given both the ad hoc and the playbook form of execution.

as AD-HOC Command

$ ansible testservers -m command -a uptime -i ansible_hosts

wmivmapp01 | CHANGED | rc=0 >>
 10:43:11 up 33 min,  1 user,  load average: 0.00, 0.01, 0.05

wmiweb02 | CHANGED | rc=0 >>
 10:43:11 up 37 min,  1 user,  load average: 0.00, 0.01, 0.03 

as Playbook

---
  - name: Check the remote host uptime
    hosts: testservers
    tasks:
      - name: Execute the Uptime command over Command module
        register: uptimeoutput
        command: "uptime"

      - debug:
          var: uptimeoutput.stdout_lines

Execution of Playbook 

$ ansible-playbook AnsibleWorkSpace/ansible-command-ex1.yml -i ansible_hosts

PLAY [Check the remote host uptime] **************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************
ok: [wmiweb002]
ok: [wmivmapp001]

TASK [Execute the Uptime command over Command module] ********************************************************************************************************
changed: [wmiweb02]
changed: [wmivmapp01]

TASK [debug] *************************************************************************************************************************************************
ok: [wmiweb002] => {
    "uptimeoutput.stdout_lines": [
        " 11:15:15 up  1:08,  1 user,  load average: 0.01, 0.02, 0.04"
    ]
}
ok: [wmivmapp001] => {
    "uptimeoutput.stdout_lines": [
        " 11:15:15 up  1:05,  1 user,  load average: 0.01, 0.02, 0.05"
    ]
}

PLAY RECAP ***************************************************************************************************************************************************
wmivmapp01                 : ok=3    changed=1    unreachable=0    failed=0   
wmiweb02                   : ok=3    changed=1    unreachable=0    failed=0

Example 02: Get the Hostname and Version of  remote servers with UNAME

we have used the command module and executing an uname -a command

as AD-HOC command

$ ansible testservers -m command -a "uname -a" -i ansible_hosts

wmiweb02 | CHANGED | rc=0 >>
Linux wmiweb02 3.10.0-693.11.1.el7.x86_64 #1 SMP Mon Dec 4 23:52:40 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

wmivmapp01 | CHANGED | rc=0 >>
Linux wmivmapp01 3.10.0-693.11.1.el7.x86_64 #1 SMP Mon Dec 4 23:52:40 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

As Playbook

---
  - name: Check the remote host Hostname, Version, Distribution with UNAME
    hosts: testservers
    tasks:
      - name: Execute the UNAME command
        register: unameout
        command: "uname -a"

      - debug:
          var: unameout.stdout_lines

Execution of Playbook

$ ansible-playbook AnsibleWorkSpace/ansible-command-execution2.yml -i ansible_hosts

PLAY [Check the remote host Hostname, Version, Distribution with UNAME] **************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************
ok: [wmiweb02]
ok: [wmivmapp01]

TASK [Execute the UNAME command] *****************************************************************************************************************************
changed: [wmiweb02]
changed: [wmivmapp01]

TASK [debug] *************************************************************************************************************************************************
ok: [wmiweb02] => {
    "unameout.stdout_lines": [
        "Linux wmiweb02 3.10.0-693.11.1.el7.x86_64 #1 SMP Mon Dec 4 23:52:40 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux"
    ]
}
ok: [wmivmapp01] => {
    "unameout.stdout_lines": [
        "Linux wmivmapp01 3.10.0-693.11.1.el7.x86_64 #1 SMP Mon Dec 4 23:52:40 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux"
    ]
}

PLAY RECAP ***************************************************************************************************************************************************
wmivmapp01                 : ok=3    changed=1    unreachable=0    failed=0   
wmiweb02                   : ok=3    changed=1    unreachable=0    failed=0   

Example 03: Check the Disk Usage of Remote server

To get the disk usage, we are using df -h , here -h is human readable

As Ad Hoc command

$ ansible testservers -m command -a "df -h" -i ansible_hosts

wmiweb002 | CHANGED | rc=0 >>
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   50G  1.2G   49G   3% /
devtmpfs                 909M     0  909M   0% /dev
tmpfs                    920M     0  920M   0% /dev/shm
tmpfs                    920M  8.5M  912M   1% /run
tmpfs                    920M     0  920M   0% /sys/fs/cgroup
/dev/sda1               1014M  171M  844M  17% /boot
/dev/mapper/centos-home   28G   33M   28G   1% /home
admin                  112G   88G   24G  79% /admin
tmpfs                    184M     0  184M   0% /run/user/0
tmpfs                    184M     0  184M   0% /run/user/1000

wmivmapp001 | CHANGED | rc=0 >>
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   50G  1.4G   49G   3% /
devtmpfs                 909M     0  909M   0% /dev
tmpfs                    920M     0  920M   0% /dev/shm
tmpfs                    920M  8.5M  912M   1% /run
tmpfs                    920M     0  920M   0% /sys/fs/cgroup
/dev/sda1               1014M  171M  844M  17% /boot
/dev/mapper/centos-home   28G   33M   28G   1% /home
admin                  112G   88G   24G  79% /admin
tmpfs                    184M     0  184M   0% /run/user/0
tmpfs                    184M     0  184M   0% /run/user/1000

As Playbook

---
  - name: Check the disk usage of all the file system in the remote servers
    hosts: testservers
    tasks:
      - name: Execute the df command
        register: dfout
        command: "df -h"

      - debug:
          var: dfout.stdout_lines

Example 04: Restart Apache Server using Ansible Command Module

So far, In all the sample we have seen we are using one application server and one web server. Totally two servers.

But in this Example, we need to limit our execution only to the web server as we are going to check the restart the apache web server.

this is done using --limit parameter

As Ad hoc command

$ ansible testservers -m command -a "httpd -k restart" -i ansible_hosts -b --limit wmiweb02
wmiweb02 | CHANGED | rc=0 >>

As Playbook

---
  - name: restart apache web server
    hosts: testservers
    tasks:
      - name: restartapache
        register: httpdresout
        become: yes
        command: "httpd -k restart"
        when: ansible_hostname == "wmiweb02"


      - debug:
          var: httpdresout.stdout_lines

Playbook Execution

From the Output you can notice that the application server is skipped

$ ansible-playbook restarthttpd.yml -i ansible_hosts

PLAY [restart apache web server] *************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************
ok: [wmiweb02]
ok: [wmivmapp01]

TASK [Execute the df command] ****************************************************************************************************************************************************
skipping: [wmivmapp01]
changed: [wmiweb02]

TASK [debug] *********************************************************************************************************************************************************************
ok: [wmiweb02] => {
    "httpdresout.stdout_lines": []
}
ok: [wmivmapp01] => {
    "httpdresout.stdout_lines": "VARIABLE IS NOT DEFINED!"
}

PLAY RECAP ***********************************************************************************************************************************************************************
wmivmapp01                 : ok=2    changed=0    unreachable=0    failed=0
wmiweb02                   : ok=3    changed=1    unreachable=0    failed=0

Example 05: Execute a command when a file exists or not exists

There are two most useful parameters in ansible command module such as removes and creates

removes – used to tell ansible to Execute the command only if the file exist

creates – used to tell ansible to Execute the specified command only if the file does not exist

Here we are going to do a very simple file creation and removal based on the file availability or existence. In General using the ansible command module, This method of creating and removing the file is not recommended as Ansible has a dedicated module named file to do the same effortlessly.

As Ad hoc command

Remove the file, if it does exist (or) present

$ ansible testservers -a "rm -rf /tmp/testfile  removes=/tmp/testfile" -i ansible_hosts
 
wmiweb02 | CHANGED | rc=0 >>
wmivmapp01 | CHANGED | rc=0 >>

Create  the file, if it does NOT exist (or) absent

$ ansible testservers -a "touch /tmp/testfile  creates=/tmp/testfile" -i ansible_hosts

wmivmapp01 | CHANGED | rc=0 >>
wmiweb02 | CHANGED | rc=0 >>

As Playbook

---
 - name: "Validate if a file is present or not present using Ansible Command module"
   hosts: testservers
   tasks:
    - name: "Create a file if it does not exist"
      command: "touch /tmp/latestfile"
      args:
         creates: "/tmp/latestfile"
      register: createif

    - name: "Display the file to make sure its created"
      command: "ls -lrt /tmp/latestfile"
      register: displayif
      when: createif is changed

    - debug: var=displayif.stdout

    - name: "Remove the file if it exist"
      command: "rm -rf /tmp/latestfile"
      args:
         removes: "/tmp/latestfile"
      register: removeif

In the playbook we execute three tasks,

  • First one is a create a file if it does not exist
  • Second to display if the creation is successful
  • Third one is to delete the file if it exists

Playbook Execution Result

this is the execution result  or output the preceding playbook. this playbook would return the same result despite run multiple times cause we create, validate and we remove at each execution.

$ ansible-playbook AnsibleWorkSpace/commandex-existnot.yml -i ansible_hosts

PLAY [Validate if a file is present or not present using Ansible Command module] *************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************
ok: [wmivmapp01]
ok: [wmiweb02]

TASK [Create a file if it does not exist] ****************************************************************************************************************************************
changed: [wmivmapp01]
changed: [wmiweb02]

TASK [Display the file to make sure its created] *********************************************************************************************************************************
changed: [wmiweb02]
changed: [wmivmapp01]

TASK [debug] *********************************************************************************************************************************************************************
ok: [wmiweb02] => {
    "displayif.stdout": "-rw-rw-r--. 1 admin admin 0 Apr 13 19:55 /tmp/latestfile"
}
ok: [wmivmapp01] => {
    "displayif.stdout": "-rw-rw-r--. 1 admin admin 0 Apr 13 19:55 /tmp/latestfile"
}

TASK [Remove the file if it exist] ***********************************************************************************************************************************************
changed: [wmiweb02]
changed: [wmivmapp01]

PLAY RECAP ***********************************************************************************************************************************************************************
wmivmapp01                 : ok=5    changed=3    unreachable=0    failed=0
wmiweb02                   : ok=5    changed=3    unreachable=0    failed=0

Example 05: Execute or Run the Script when a file exists or not exists

Now for this example, let’s take something related to a real world scenario. Like Start server version program (or) if PID file or LOCK file does not exist

Here’s an example playbook to get you started. I’m giving a general guide here because I don’t want to choose my own server/technology that you can’t relate to.

You can feel free to modify the script as needed as this is just a template.

---
 - name: Start of Stop Server instance based on PID/LOCK file availability
   hosts: appservers
   tasks:
      - name: Start the instance when the PID file is not present
        become: yes
        become_user: appuser
        command: "startserver.sh"
        args:
          creates: "/path/to/pid/instance.pid"
        register: startinst

      - name: Stop the instance when the lock file is present
        become: yes
        become_user: appuser
        command: "stopserver.sh"
        args:
          removes: "/path/to/lockfile/instance.lck"
        register: stopinst

A Quick Additional Info

Ansible Command Module is the Default Module of “Ansible” CLI, Which means, You can write your AD HOC command in both the following forms and both are correct

ansible testservers -m command -a uptime -i ansible_hosts

or

ansible testservers  -a uptime -i ansible_hosts

To verify, Try executing ansible --help in your control master/host and read it through.

comments powered by Disqus