Ansible Playbook to run Shell commands
Categories:
Mastering Shell Commands with Ansible Playbooks

Learn how to effectively execute shell commands on remote servers using Ansible playbooks, covering common use cases for NGINX and uWSGI management.
Ansible is a powerful automation engine that simplifies configuration management, application deployment, and task automation. While Ansible provides a rich set of modules for various tasks, there are times when directly executing shell commands is the most straightforward or necessary approach. This article will guide you through using Ansible's shell
and command
modules to run arbitrary commands on your managed nodes, with practical examples for managing services like NGINX and uWSGI.
Understanding Ansible's Shell and Command Modules
Ansible offers two primary modules for executing commands: command
and shell
. Understanding their differences is crucial for writing secure and effective playbooks. The command
module is simpler and safer, as it does not process variables or shell features like redirection (>
), pipes (|
), or environment variables. It's best used for basic command execution where no shell interpretation is needed. The shell
module, on the other hand, executes commands through a shell (typically /bin/sh
or /bin/bash
), allowing for advanced shell features. This flexibility comes with increased risk if not used carefully, as it can be susceptible to shell injection vulnerabilities if inputs are not properly sanitized.
command
module over shell
unless you specifically require shell features. This minimizes potential security risks and ensures your commands behave predictably.- name: Basic command module example
command: uptime
- name: Basic shell module example with pipe
shell: ps aux | grep nginx
Managing NGINX with Ansible Shell Commands
NGINX is a popular web server often managed via its service commands or direct configuration file manipulation. Ansible can streamline these tasks. For instance, restarting NGINX after a configuration change is a common operation. While Ansible has a dedicated service
module, using shell
can be useful for specific scenarios, such as checking NGINX configuration syntax before a reload or restart, or interacting with custom NGINX scripts.
flowchart TD A[Start Ansible Playbook] --> B{NGINX Config Change?} B -- Yes --> C[Copy New NGINX Config] C --> D{"Check NGINX Config Syntax (shell: nginx -t)"} D -- OK --> E["Reload NGINX (shell: systemctl reload nginx)"] D -- Error --> F[Fail Playbook] E --> G[End] B -- No --> G
Workflow for NGINX Configuration Update and Reload
- name: Check NGINX configuration syntax
shell: nginx -t
register: nginx_check
failed_when: nginx_check.rc != 0
changed_when: false
- name: Reload NGINX service
shell: systemctl reload nginx
become: true
listen: "nginx_config_changed"
listen
keyword in Ansible allows tasks to be triggered only when a handler with a matching name is notified. This is a powerful way to ensure service restarts only happen when necessary.Controlling uWSGI Applications
uWSGI is a highly performant application server often used for Python web applications. Managing uWSGI processes, especially when running in Emperor mode or with specific configuration files, often involves sending signals or executing custom scripts. The shell
module is particularly useful here for tasks like gracefully restarting uWSGI workers or checking the status of uWSGI instances.
- name: Gracefully restart a uWSGI application
shell: kill -HUP $(cat /var/run/uwsgi/my_app.pid)
become: true
- name: Check uWSGI process status
shell: ps aux | grep uwsgi | grep -v grep
register: uwsgi_status
changed_when: false
- name: Display uWSGI status
debug:
msg: "{{ uwsgi_status.stdout_lines }}"
shell
with kill
commands, ensure you are targeting the correct process IDs. Incorrect usage can lead to unintended application downtime or data loss. Always test such commands in a controlled environment first.By leveraging Ansible's shell
and command
modules, you gain fine-grained control over your remote systems, enabling you to automate a wide array of tasks that might not be directly covered by existing Ansible modules. Remember to prioritize security by using command
whenever possible and exercising caution with shell
.