Examples

20+ Ansible Playbook Examples for Common Tasks

Teach me Ansible | 2025-01-12 | 25 min read

20+ practical Ansible playbook examples for everyday automation tasks. Copy, paste, and adapt these ready-to-use playbooks for your infrastructure.

System Administration

1. User Management

---
- name: Manage System Users
  hosts: all
  become: yes
  tasks:
    - name: Create user with sudo access
      user:
        name: devops
        groups: sudo
        shell: /bin/bash
        create_home: yes
        state: present

    - name: Add SSH key
      authorized_key:
        user: devops
        key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
        state: present

2. Package Installation Across Distributions

---
- name: Install packages on different OS
  hosts: all
  become: yes
  tasks:
    - name: Install on Debian/Ubuntu
      apt:
        name: [nginx, git, curl]
        state: present
        update_cache: yes
      when: ansible_os_family == "Debian"

    - name: Install on RHEL/CentOS
      yum:
        name: [nginx, git, curl]
        state: present
      when: ansible_os_family == "RedHat"

3. Service Management

---
- name: Manage Services
  hosts: webservers
  become: yes
  tasks:
    - name: Ensure services are running
      service:
        name: "{{ item }}"
        state: started
        enabled: yes
      loop:
        - nginx
        - mysql
        - redis

    - name: Restart service if config changed
      service:
        name: nginx
        state: restarted
      when: nginx_config.changed

4. Disk Space Cleanup

---
- name: Clean Up Disk Space
  hosts: all
  become: yes
  tasks:
    - name: Remove old log files
      find:
        paths: /var/log
        age: 30d
        patterns: "*.log"
      register: old_logs

    - name: Delete old logs
      file:
        path: "{{ item.path }}"
        state: absent
      loop: "{{ old_logs.files }}"

    - name: Clean apt cache (Ubuntu/Debian)
      command: apt-get clean
      when: ansible_os_family == "Debian"

    - name: Display disk usage
      shell: df -h /
      register: disk_usage

    - debug:
        var: disk_usage.stdout_lines

Security & Hardening

5. SSH Hardening

---
- name: Harden SSH Configuration
  hosts: all
  become: yes
  tasks:
    - name: Update SSH config
      lineinfile:
        path: /etc/ssh/sshd_config
        regexp: "{{ item.regexp }}"
        line: "{{ item.line }}"
      loop:
        - {regexp: '^PermitRootLogin', line: 'PermitRootLogin no'}
        - {regexp: '^PasswordAuthentication', line: 'PasswordAuthentication no'}
        - {regexp: '^Port', line: 'Port 2222'}
      notify: restart sshd

  handlers:
    - name: restart sshd
      service:
        name: sshd
        state: restarted

6. Firewall Configuration

---
- name: Configure UFW Firewall
  hosts: webservers
  become: yes
  tasks:
    - name: Install UFW
      apt:
        name: ufw
        state: present

    - name: Allow SSH
      ufw:
        rule: allow
        port: '22'
        proto: tcp

    - name: Allow HTTP/HTTPS
      ufw:
        rule: allow
        port: "{{ item }}"
        proto: tcp
      loop: ['80', '443']

    - name: Enable UFW
      ufw:
        state: enabled
        policy: deny

Web Server Deployment

7. Nginx Installation and Configuration

---
- name: Deploy Nginx Web Server
  hosts: webservers
  become: yes
  vars:
    domain_name: example.com
    web_root: /var/www/html

  tasks:
    - name: Install Nginx
      apt:
        name: nginx
        state: present

    - name: Create web root
      file:
        path: "{{ web_root }}"
        state: directory
        owner: www-data
        group: www-data

    - name: Deploy site config
      template:
        src: nginx-site.conf.j2
        dest: "/etc/nginx/sites-available/{{ domain_name }}"
      notify: reload nginx

    - name: Enable site
      file:
        src: "/etc/nginx/sites-available/{{ domain_name }}"
        dest: "/etc/nginx/sites-enabled/{{ domain_name }}"
        state: link
      notify: reload nginx

  handlers:
    - name: reload nginx
      service:
        name: nginx
        state: reloaded

8. SSL Certificate with Let's Encrypt

---
- name: Install SSL Certificate
  hosts: webservers
  become: yes
  vars:
    domain: example.com
    email: admin@example.com

  tasks:
    - name: Install Certbot
      apt:
        name: [certbot, python3-certbot-nginx]
        state: present

    - name: Obtain certificate
      command: >
        certbot --nginx
        -d {{ domain }}
        -d www.{{ domain }}
        --non-interactive
        --agree-tos
        --email {{ email }}
      args:
        creates: "/etc/letsencrypt/live/{{ domain }}/fullchain.pem"

    - name: Auto-renewal cron
      cron:
        name: "Renew SSL"
        minute: "0"
        hour: "3"
        job: "certbot renew --quiet"

Database Management

9. MySQL Installation and User Creation

---
- name: Setup MySQL Database
  hosts: databases
  become: yes
  vars:
    mysql_root_password: "{{ vault_mysql_root_password }}"
    db_name: myapp
    db_user: myapp_user
    db_password: "{{ vault_db_password }}"

  tasks:
    - name: Install MySQL
      apt:
        name: [mysql-server, python3-pymysql]
        state: present

    - name: Start MySQL
      service:
        name: mysql
        state: started
        enabled: yes

    - name: Create database
      mysql_db:
        name: "{{ db_name }}"
        state: present
        login_unix_socket: /var/run/mysqld/mysqld.sock

    - name: Create user
      mysql_user:
        name: "{{ db_user }}"
        password: "{{ db_password }}"
        priv: "{{ db_name }}.*:ALL"
        state: present
        login_unix_socket: /var/run/mysqld/mysqld.sock

10. PostgreSQL Backup

---
- name: Backup PostgreSQL Database
  hosts: databases
  become: yes
  vars:
    backup_dir: /var/backups/postgresql
    db_name: myapp

  tasks:
    - name: Create backup directory
      file:
        path: "{{ backup_dir }}"
        state: directory
        mode: '0700'

    - name: Backup database
      postgresql_db:
        name: "{{ db_name }}"
        state: dump
        target: "{{ backup_dir }}/{{ db_name }}_{{ ansible_date_time.date }}.sql"

    - name: Remove old backups (keep 7 days)
      find:
        paths: "{{ backup_dir }}"
        age: 7d
        patterns: "*.sql"
      register: old_backups

    - name: Delete old backups
      file:
        path: "{{ item.path }}"
        state: absent
      loop: "{{ old_backups.files }}"

Monitoring & Logging

11. Install and Configure Prometheus Node Exporter

---
- name: Deploy Prometheus Node Exporter
  hosts: all
  become: yes
  tasks:
    - name: Download Node Exporter
      get_url:
        url: https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz
        dest: /tmp/node_exporter.tar.gz

    - name: Extract Node Exporter
      unarchive:
        src: /tmp/node_exporter.tar.gz
        dest: /usr/local/bin
        remote_src: yes
        extra_opts: [--strip-components=1]

    - name: Create systemd service
      copy:
        dest: /etc/systemd/system/node_exporter.service
        content: |
          [Unit]
          Description=Node Exporter

          [Service]
          User=nobody
          ExecStart=/usr/local/bin/node_exporter

          [Install]
          WantedBy=multi-user.target

    - name: Start Node Exporter
      systemd:
        name: node_exporter
        state: started
        enabled: yes
        daemon_reload: yes

12. Centralized Logging Setup

---
- name: Configure Rsyslog for Central Logging
  hosts: all
  become: yes
  vars:
    log_server: 192.168.1.100

  tasks:
    - name: Configure rsyslog to forward logs
      lineinfile:
        path: /etc/rsyslog.conf
        line: "*.* @@{{ log_server }}:514"
        state: present
      notify: restart rsyslog

  handlers:
    - name: restart rsyslog
      service:
        name: rsyslog
        state: restarted

Docker & Containers

13. Install Docker

---
- name: Install Docker
  hosts: all
  become: yes
  tasks:
    - name: Install dependencies
      apt:
        name: [apt-transport-https, ca-certificates, curl, gnupg, lsb-release]
        state: present

    - name: Add Docker GPG key
      apt_key:
        url: https://download.docker.com/linux/ubuntu/gpg
        state: present

    - name: Add Docker repository
      apt_repository:
        repo: "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable"
        state: present

    - name: Install Docker
      apt:
        name: [docker-ce, docker-ce-cli, containerd.io]
        state: present
        update_cache: yes

    - name: Add user to docker group
      user:
        name: "{{ ansible_user }}"
        groups: docker
        append: yes

14. Deploy Docker Compose Application

---
- name: Deploy with Docker Compose
  hosts: docker_hosts
  become: yes
  tasks:
    - name: Install docker-compose
      get_url:
        url: https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-linux-x86_64
        dest: /usr/local/bin/docker-compose
        mode: '0755'

    - name: Create app directory
      file:
        path: /opt/myapp
        state: directory

    - name: Copy docker-compose.yml
      copy:
        src: docker-compose.yml
        dest: /opt/myapp/docker-compose.yml

    - name: Start containers
      command: docker-compose up -d
      args:
        chdir: /opt/myapp

Maintenance & Updates

15. System Updates

---
- name: Update All Systems
  hosts: all
  become: yes
  tasks:
    - name: Update apt cache (Debian/Ubuntu)
      apt:
        update_cache: yes
        cache_valid_time: 3600
      when: ansible_os_family == "Debian"

    - name: Upgrade all packages
      apt:
        upgrade: dist
      when: ansible_os_family == "Debian"

    - name: Update yum packages (RHEL/CentOS)
      yum:
        name: '*'
        state: latest
      when: ansible_os_family == "RedHat"

    - name: Check if reboot required
      stat:
        path: /var/run/reboot-required
      register: reboot_required

    - name: Reboot if required
      reboot:
        msg: "Reboot initiated by Ansible"
        reboot_timeout: 600
      when: reboot_required.stat.exists

16. Health Check and Reporting

---
- name: System Health Check
  hosts: all
  gather_facts: yes
  tasks:
    - name: Check disk usage
      shell: df -h / | tail -1 | awk '{print $5}' | sed 's/%//'
      register: disk_usage
      changed_when: false

    - name: Alert if disk > 80%
      debug:
        msg: "WARNING: Disk usage is {{ disk_usage.stdout }}%"
      when: disk_usage.stdout|int > 80

    - name: Check memory usage
      shell: free | grep Mem | awk '{print ($3/$2) * 100.0}'
      register: mem_usage
      changed_when: false

    - name: Check service status
      service_facts:

    - name: Verify critical services
      fail:
        msg: "{{ item }} is not running!"
      when: services[item + '.service'].state != 'running'
      loop:
        - nginx
        - mysql
      ignore_errors: yes

Quick Start

Copy any example and run: ansible-playbook example.yml
Test first with: ansible-playbook example.yml --check

Conclusion

These 16 playbook examples cover the most common automation tasks. Adapt them to your infrastructure, combine multiple tasks, and build comprehensive automation workflows!