Ansible Playbooks Collection

Sanitized, reusable Ansible playbooks with secure defaults and toggleable views.

Ansible Setup:

If you do not have an Ansible controller, inventory, or vault configured, start here:

  • Ansible Setup Lab


  • 1. Linux User & Admin Group Provisioning

    Creates admin group, configures sudo, and provisions multiple users.

    
    ---
    - name: Configure Admin Group, Sudoers, and Provision Users
      hosts: wain
      vars_files:
        - /path/to/secrets.yml
      gather_facts: no
      
      vars:
        ansible_password: "{{ 1_pwd }}"
        ansible_user: "{{ 1_username }}"
        ansible_become: yes
        ansible_become_method: sudo
        ansible_become_user: root
        ansible_become_password: "{{ 1_pwd }}"
        admin_group: "admin"
        users:
          - user1
          - user2
        selinux_user: "staff_u"
        selinux_range: "s0-s0:c0.c1023"
    
      tasks:
        ## SECTION 1: Group & Sudo Configuration ##
        
        - name: Ensure the admin group exists
          ansible.builtin.group:
            name: "{{ admin_group }}"
            state: present
    
        - name: Create sudoers.d file for the admin group
          ansible.builtin.copy:
            dest: "/etc/sudoers.d/{{ admin_group | lower }}"
            content: "%{{ admin_group }} ALL=(ALL) ALL"
            mode: '0440'
            validate: '/usr/sbin/visudo -cf %s'
    
        ## SECTION 2: User Provisioning ##
    
        - name: Ensure per-user private groups exist
          ansible.builtin.group:
            name: "{{ item }}"
            state: present
          loop: "{{ users }}"
    
        - name: Create user accounts and assign groups
          ansible.builtin.user:
            name: "{{ item }}"
            group: "{{ item }}"
            groups: "{{ admin_group }}"
            append: yes
            create_home: yes
            state: present
            password: ""
          loop: "{{ users }}"
    
        - name: Create user .ssh directory
          ansible.builtin.file:
            path: "/home/{{ item }}/.ssh"
            state: directory
            owner: "{{ item }}"
            group: "{{ item }}"
            mode: '0700'
          loop: "{{ users }}"
    
        - name: Force password change on first login
          ansible.builtin.command:
            cmd: "chage -d 0 {{ item }}"
          loop: "{{ users }}"
          changed_when: true
    
        - name: Set SELinux login assignments
          ansible.builtin.command:
            cmd: "semanage login -a -s {{ selinux_user }} -r {{ selinux_range }} {{ item }}"
          loop: "{{ users }}"
    
    
    
    2. Elastic Stack Health Checks

    Validates core Elastic Stack services across host groups.

    
    ---
    - name: Check Elastic Services
      hosts: elastic_nodes
      vars_files:
        - /path/to/vault.yml
      gather_facts: no
    
      vars:
        ansible_user: "{{ vault_user }}"
        ansible_password: "{{ vault_password }}"
        ansible_become: yes
        ansible_become_method: sudo
        ansible_become_user: root
        ansible_become_password: "{{ vault_password }}"
        services:
          - elasticsearch
          - logstash
          - kibana
          - elastic-agent
    
      tasks:
        - name: Check service status
          ansible.builtin.systemd:
            name: "{{ item }}"
            state: started
          register: svc
          ignore_errors: yes
          changed_when: false
          loop: "{{ services }}"
    
    
    
    3. Server Reboot Playbook

    Safely reboots infrastructure nodes.

    
    ---
    - name: Reboot Servers
      hosts: infrastructure_nodes
      vars_files:
        - /path/to/vault.yml
      gather_facts: no
    
      vars:
        ansible_user: "{{ vault_user }}"
        ansible_password: "{{ vault_password }}"
        ansible_become: yes
        ansible_become_method: sudo
        ansible_become_user: root
        ansible_become_password: "{{ vault_password }}"
    
      tasks:
        - name: Reboot system
          ansible.builtin.reboot:
            reboot_timeout: 600
    
    
    
    4. Sensor Health Check

    Checks the health of various services on sensor devices (e.g., Zeek, Tcpdump, Snort) and disk usage.

    
    ---
    - name: Sensor Health Check
      hosts: all
      vars_files:
        - -path to secrets file-
      gather_facts: no
      vars:
        ansible_password: "{{ sensors_pwd2 }}"
        ansible_user: " {{ sensor_health }}"
        ansible_become_method: sudo
        ansible_become_user: root
        ansible_become_password: "{{ sensors_pwd2 }}"
        ansible_become: yes
      tasks:
        - name: Check Zeek service status
          ansible.builtin.systemd:
            name: zeek
            state: started
          become: yes
          become_user: root
          become_method: sudo
          register: zeek_status
          ignore_errors: yes
          changed_when: false
    
        - name: Display Zeek status
          ansible.builtin.debug:
            msg: "Zeek is {{ 'running' if zeek_status.status.ActiveState == 'active' else 'not running' }}"
          when: zeek_status.status is defined
    
        - name: Check Tcpdump service status
          ansible.builtin.systemd:
            name: tcpdump
            state: started
          become: yes
          become_user: root
          become_method: sudo
          register: tcpdump_status
          ignore_errors: yes
          changed_when: false
    
        - name: Display Tcpdump status
          ansible.builtin.debug:
            msg: "Tcpdump is {{ 'running' if tcpdump_status.status.ActiveState == 'active' else 'not running' }}"
          when: tcpdump_status.status is defined
    
        - name: Check Snort service status
          ansible.builtin.systemd:
            name: snort
            state: started
          become: yes
          become_user: root
          become_method: sudo
          register: snort_status
          ignore_errors: yes
          changed_when: false
    
        - name: Display Snort status
          ansible.builtin.debug:
            msg: "Snort is {{ 'running' if snort_status.status.ActiveState == 'active' else 'not running' }}"
          when: snort_status.status is defined
    
        - name: Check disk usage
          ansible.builtin.command: df -h
          become: yes
          become_user: root
          become_method: sudo
          register: disk_usage
          changed_when: false
          failed_when: false
    
        - name: Parse disk usage for 100% full filesystems
          ansible.builtin.set_fact:
            full_disks: "{{ disk_usage.stdout_lines | select('match', '.*100%.*') | list }}"
          no_log: true
    
        - name: Display 100% full filesystems
          ansible.builtin.debug:
            msg: "{{ item }}"
          loop: "{{ full_disks }}"
          when: full_disks | length > 0
    
        - name: Find large files on 100% full filesystems
          ansible.builtin.command: find / -xdev -type f -size +100M -exec ls -lah {} + | sort -hr -k 5 | head -n 5
          become: yes
          become_user: root
          become_method: sudo
          register: large_files
          changed_when: false
          failed_when: false
          when: full_disks | length > 0
    
        - name: Display large files
          ansible.builtin.debug:
            msg: "{{ item }}"
          loop: "{{ large_files.stdout_lines }}"
          when: large_files.stdout_lines is defined and full_disks | length > 0
    
    
    
    5. Resource Check Playbook

    Checks storage, memory, and CPU usage on Elastic nodes.

    
    ---
    - name: Check Elastic Node Stats
      hosts: all
      vars_files:
        - -path to secrets file-
      gather_facts: no
      vars:
        ansible_password: "{{ newelastic_pwd }}"
        ansible_user: "{{ elastic_user }}"
        ansible_become_method: sudo
        ansible_become_user: root
        ansible_become_password: "{{ newelastic_pwd }}"
        ansible_become: yes
      tasks:
        - name: Check Storage amount
          ansible.builtin.command: df -h --total
          become: yes
          become_user: root
          become_method: sudo su
          register: ES_df
          ignore_errors: yes
          changed_when: false
    
        - name: Display storage total
          ansible.builtin.debug:
            msg: "Node storage: {{ ES_df.stdout }}"
          when: ES_df is defined and ES_df.stdout is defined
    
        - name: Check Memory amount
          ansible.builtin.command: free -h
          become: yes
          become_user: root
          become_method: sudo su
          register: ES_free
          ignore_errors: yes
          changed_when: false
    
        - name: Display mem total
          ansible.builtin.debug:
            msg: "Node memory: {{ ES_free.stdout }}"
          when: ES_free is defined and ES_free.stdout is defined
    
        - name: Check CPU amount
          ansible.builtin.command: lscpu
          become: yes
          become_user: root
          become_method: sudo su
          register: ES_lscpu
          ignore_errors: yes
          changed_when: false
    
        - name: Display CPU amount
          ansible.builtin.debug:
            msg: "Node CPU: {{ ES_lscpu.stdout }}"
          when: ES_lscpu is defined and ES_lscpu.stdout is defined
    
    
    
    6. SED Replace Playbook

    Uses sed to find and replace a line in a file across multiple devices (e.g., journald.conf).

    
    ---
    - name: Add persistence to journald.conf
      hosts: all
      vars_files:
        - /path/to/secrets.yml
      gather_facts: no
      vars:
        ansible_password: "{{ sensors_pwd2 }}"
        ansible_user: "{{ sensor_user }}"
        ansible_become_method: sudo
        ansible_become_user: root
        ansible_become_password: "{{ sensors_pwd2 }}"
        ansible_become: yes
      tasks:
        - name: fix journald
          ansible.builtin.command: sed -i 's/#Storage=auto/Storage=persistent/g' /etc/systemd/journald.conf
          become: yes
          become_user: root
          become_method: sudo
          ignore_errors: yes
          changed_when: false