Learn How to Execute Remote Commands With Ansible Shell Module

Ansible is a popular automation platform that allows you to manage many f nodes simultaneously. One of the most useful features of Ansible is its ability to run ad-hoc commands on remote computers with the Ansible shell module. Using this module, we can run complex commands and shell scripts on remote hosts.

In this blog, we use multiple examples to demonstrate the different use cases of the Ansible Shell module.

Welcome to KodeKloud!

We are the #1 DevOps courses provider. Join us today to gain access to our free courses and labs and try sample lessons of all 65+ courses. No credit card required!

REGISTER

What is Ansible Shell Module?

Ansible is an open-source automation platform used for configuring and managing IT infrastructure. Ansible's shell module allows you to execute commands on remote hosts. By default, it utilizes the /bin/sh command shell, though other choices may be specified if necessary.

Below are the parameters used with the Ansible Shell module:

  • cmd: We need to give a command to be executed below this parameter.
  • chdir: This parameter is used to change the path of the directory before running the command.
  • creates: This parameter will not run the command if the mentioned filename exists.
  • executables: We need to give the path of the executable from where the executable will run.
  • removes: It checks for a filename, and if it does not exist, then the command will not run.
  • stdin: To set the stdin of the command.
  • stdin_add_newline: Default is yes. This is to add a new line to stdin data.
  • warn: Default is yes. This enables task warning.

How Ansible Shell Module Works?

Ansible's shell module works by connecting to a remote host and executing the command that has been provided. It uses SSH protocol to connect to remote hosts and run commands and scripts on them.

The shell module supports various options that you can use to tailor how a command is executed, including executable and chdir options that specify where it should run (i.e., in an executable shell or directory environment). It also provides you with return codes to determine the status of a command. A return code of 0 signifies success, while a return code of 1 indicates failure.

Using Ansible Shell Module

The shell module is very straightforward and user-friendly. To run remote commands with a shell module, you simply specify the command in a playbook. The following playbook, for instance, will execute the ls command and list all the files in the home directory on remote webservers.

---
- name: Running a command
  hosts: webservers
  tasks:
    - name: Run ls command
      shell: ls

To run this playbook, you would use the following command:

ansible-playbook playbook.yml

The ansible-playbook command will connect to the remote host webserver and execute the ls command. The output of the command will be displayed in your terminal.

The shell module has a number of other options that you can use to control how the command is executed. For example, you can use the executable option to specify the shell that you want to use and the chdir option to specify the directory that you want the command to be executed in.

To run multiple commands sequentially on a remote host, just separate each command with a pipe character |. For instance, this playbook will execute two separate commands, one after the other, on the webservers.

---
- name: Running multiple commands
  hosts: webservers
  tasks:
    - name: Run ls and pwd commands
      shell: ls . | wc -l

The ls . command will fetch all the files in the directory where it is executed and the wc -l will count those files.

Passing Variables to a Shell Module

You can also pass variables directly to the shell module. If you want to execute a command that contains variables, you can use the {{ variable_name }} syntax. For instance, in this playbook, we will run the echo command, passing ‘hostname’ as an argument and replacing its value with that of the remote host before running the command.

---
- name: Passing Variable
  hosts: webservers
  tasks:
  - name: Run echo command with variable
    shell: echo {{ hostname }}

Saving the Output of a Shell Command

By default, shell commands print their output directly to the console; however, you have the option of saving this output to a file by specifying the stdout parameter as either a filename or path to a directory - either will work. When specifying either option as filenames or directories, respectively, any output generated will be saved into that specified directory.

Here is an example playbook to execute ls command on remote webservers and save the output as file /tmp/ls_output.txt.

---
- name: Saving output
  hosts: webservers
  tasks:
  - name: Run ls command and save the output
    shell: ls
    stdout: /tmp/ls_output.txt

Installing Packages

Below is an example showing how to install an Apache package on the remote hosts, which are webservers:

---
- name: Installing Packages
  hosts: webservers
  tasks:
    - name: Install Apache
      shell: apt-get install -y apache2
      become: true

This example demonstrates installing the Apache web server on remote servers using the apt-get package manager. The apt-get install -y apache2 command installs Apache without prompting for confirmation.

Restarting a Service

Below is an example to restart the Apache service on remote webservers:

---
- name: Restart a Service
  hosts: webservers
  tasks:
  - name: Restart Apache
    shell: systemctl restart apache2
    become: true

Here, the systemctl restart apache2 command is used to restart the Apache service on the remote servers. The systemctl command is specific to systems that use systemd for service management.

Run a Command Using Shell Module if a File Does Not Exist

The creates parameter allows you to run a command if a file does not exist. It specifies the path to the file, which, if it exists, the command to be executed is skipped.

The playbook shown checks if the file hello.txt exists in the home directory of the target host. If the file is absent, then the shell command specified is executed. If the file exists, then the shell command aborts.

---
- name: Create a file in the home directory if it doesn't exist
  hosts: webservers
  tasks:
  - name: Create a file in the home directory
    shell: echo "Hey guys!" > $HOME/hello.txt
    args:
      creates: "$HOME/hello.txt"

Managing User Accounts

Below is an example that uses the Ansible shell module to manage user accounts on remote hosts.

---
- name: Manage User Accounts
  hosts: webservers
  tasks:
  - name: Create User
    shell: useradd Alex
    become: true
 
  - name: Set Password
    shell: echo "Alex:password" | chpasswd
    become: true
 
  - name: Delete User
    shell: userdel Mary
    become: true

This example demonstrates creating a user, setting the password, and deleting a user on the remote servers. The useradd, echo, and userdel commands are used to perform these operations.

Configuring Firewall Rules

Below is an example of configuring firewall rules on remote hosts using the shell module.

---
- name: Configure Firewall
  hosts: webservers
  tasks:
  - name: Allow Port 80
    shell: iptables -A INPUT -p tcp --dport 80 -j ACCEPT
    become: true
 
  - name: Save Firewall Rules
    shell: iptables-save > /etc/iptables/rules.v4
    become: true

In this example, the iptables command is used to configure firewall rules on remote web servers. It allows incoming TCP traffic on port 80 and saves the rules to a file.

Conclusion

Ansible's Shell module makes remote command execution from a central control node easy, providing an efficient way to manage and configure your infrastructure. In this article, we saw how the Ansible shell module works and which parameters it uses. We also executed multiple examples using the Ansible shell module to execute remote commands on remote hosts.

Enroll in our Ansible Basics Course to learn more Ansible concepts with easy-to-do hands-on exercises.