Ansible Playbook to run Shell commands

Learn ansible playbook to run shell commands with practical examples, diagrams, and best practices. Covers shell, nginx, uwsgi development techniques with visual explanations.

Mastering Shell Commands with Ansible Playbooks

Hero image for Ansible Playbook to run Shell commands

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.

- 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"

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 }}"

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.