Here’s a 5-minute tutorial on the Ansible command module, which Level Up considers one of the first 10 Ansible modules you should know. We also explain how command compares and contrasts with the related shell and raw modules.

What is the Ansible Command Module?

As its name would suggest, the command module helps you execute basic commands on remote Linux hosts. (For Windows hosts, you can use the similar win_command module.) However, it’s more limited than you might think at first glance, and may not always be what you need (see below for details on alternatives like shell [similar to the win_shell module] and raw). But leveraging the command module is a straightforward and effective way for you to perform CLI tasks that do not require advanced scripting or shell-specific features.

Here’s an example of using the command module in a playbook:

# run-command.yml:
---
- name: Run a command
  hosts: all
  gather_facts: false
  vars:
    cmd: "uptime"
  tasks:
    - name: "Run command {{ cmd }}"
      ansible.builtin.command:
        cmd: "{{ cmd }}"
      register: cmd_result
    - name: "Print {{ cmd }} result"
      ansible.builtin.debug:
        msg: "{{ cmd_result.stdout_lines }}"

Beyond the absolute basics, we’ve included a couple of ideas in this playbook to help you see how easy it is to 1) effortlessly reuse your playbook for different commands in the future and 2) get exactly the output you care about.

Example output:

$ ansible-playbook run-command.yml

PLAY [Run a command] ***************************************************************************************************

TASK [Run command uptime] **********************************************************************************************
changed: [localhost]

TASK [Print uptime result] *********************************************************************************************
ok: [localhost] => {
    "msg": [
        "10:52  up 1 day,  3:24, 3 users, load averages: 2.15 2.62 2.55"
    ]
}

PLAY RECAP *************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
$
  1. By variabilizing the “cmd” near the top of the playbook, you can change it in one place in your playbook and have it apply everywhere (or override it via an extra-var).
  2. By using that Ansible workhorse of printing things to the screen, the debug module, to output only the “stdout_lines” part of the JSON data structure that came back from the command module, you are removing unnecessary details and getting right to the point.

Comparing and Contrasting the command, shell, and raw Modules

At the highest level, these things are true:

  1. command: Runs arbitrary commands but not using a shell.

2) shell: Runs arbitrary commands using a shell.

3) raw: Runs arbitrary commands directly over your network transport (e.g., SSH) without using Python on the remote host.

Going a bit deeper…

The command Module

  1. Executes commands without involving a shell. It is the recommended module for simple tasks that do not require any shell features or piping.

Pros:

  • Fast and considered more secure because it avoids shell-specific vulnerabilities.
  • Perhaps easier to understand and maintain, because it doesn’t involve complex shell scripting.

Cons:

  • Limited to simple commands without shell-specific features, like piping, redirects, or environment variable substitution.

The shell Module

  1. Allows you to execute shell commands with advanced shell features such as pipes, redirects, and environment variable substitution.

Pros:

  • Offers more flexibility than command for complex CLI tasks that may require advanced shell features.

Cons:

  • Potentially less secure than command due to potential shell injection vulnerabilities.
  • Can end up being harder to read (and therefore maintain as code), precisely because it allows complex shell scripting (which you might be better off fully Ansibilizing instead).

The raw Module

  1. Executes commands directly on the target system without any (Python-based) module processing. It is useful when working with systems that do not and cannot have Python installed.

Pros:

  • Can be used on systems without Python (e.g., your network devices).
  • Can be useful provisioning new systems with Ansible (e.g., bare metal or pre-boot interactions).

Cons:

  • Little to no error handling or reporting from Ansible– unlike nearly all other interactions that Ansible has with the hosts it automates, when you use raw, you are basically just sending a command over the network and hoping for the best.
  • Lacks the Ansible’s usual declarative/idempotent features (and often related security/error handling) provided by the command and shell modules.

Wrapping Up

In the last few minutes together, we just demoed and covered the basics of the Ansible command module, one of the first 10 Ansible modules you should know, and highlighted its key comparison points with the shell and raw modules. For simple tasks that do not require advanced shell features, the command module is probably going to be your best bet. For your more complex CLI tasks, the shell module provides you with additional functionality, but at the risk of some potential security downsides. And the raw module is probably best kept in your back pocket for systems without Python (like your networking gear, and when no collections or modules already support what you are trying to do with that gear), or when provisioning brand-new hosts via Ansible from the datacenter rack, up.

Get the latest from Level Up delivered to your inbox– DevOps Automation and Cloud news, tips & tricks.

Select list(s) to subscribe to


By submitting this form, you are consenting to receive marketing emails from: Level Up, 20929 Ventura Blvd Ste 47 #265, Woodland Hills, CA, 91364. You can revoke your consent to receive emails at any time by using the SafeUnsubscribe® link, found at the bottom of every email. Emails are serviced by Constant Contact

Spread the word. Share this post!