Configure audit compliance automation with Ansible for security monitoring and reporting

Advanced 45 min May 21, 2026 696 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Build comprehensive security audit compliance automation using Ansible playbooks to enforce security policies, monitor system configurations, and generate compliance reports across your Linux infrastructure fleet.

Prerequisites

  • Ansible control node with SSH access
  • Root or sudo privileges on target systems
  • Basic understanding of security frameworks
  • Familiarity with Ansible playbooks

What this solves

Security compliance requires continuous monitoring, policy enforcement, and regular reporting across your infrastructure. Manual compliance checks are time-consuming, error-prone, and don't scale with growing infrastructure. This tutorial shows you how to build a complete audit compliance automation system using Ansible that enforces security policies, monitors system configurations, and generates detailed compliance reports automatically.

Prerequisites

  • Ansible control node with SSH access to target hosts
  • Root or sudo privileges on all target systems
  • Basic understanding of security frameworks (CIS, NIST, SOC2)
  • Familiarity with Ansible playbooks and inventory management

Step-by-step configuration

Install and configure Linux audit framework

Start by installing the audit daemon and related tools on your target systems. The audit framework provides kernel-level monitoring of system calls, file access, and security events.

sudo apt update
sudo apt install -y auditd audispd-plugins aide rkhunter chkrootkit
sudo dnf install -y audit audit-libs aide rkhunter chkrootkit

Create Ansible directory structure

Set up a proper directory structure for your audit compliance automation project with organized roles, playbooks, and configuration files.

mkdir -p /opt/audit-compliance/{playbooks,roles,inventory,reports,templates}
cd /opt/audit-compliance

# Create role directories
mkdir -p roles/{audit-setup,compliance-check,security-hardening,reporting}/tasks
mkdir -p roles/{audit-setup,compliance-check,security-hardening,reporting}/templates
mkdir -p roles/{audit-setup,compliance-check,security-hardening,reporting}/handlers
mkdir -p roles/{audit-setup,compliance-check,security-hardening,reporting}/vars

Configure audit daemon baseline

Create an Ansible role to configure auditd with comprehensive rules for security monitoring. This establishes the foundation for compliance tracking.

---
- name: Install audit packages
  package:
    name:
      - auditd
      - audispd-plugins
      - aide
    state: present

- name: Configure auditd main configuration
  template:
    src: auditd.conf.j2
    dest: /etc/audit/auditd.conf
    backup: yes
  notify: restart auditd

- name: Deploy comprehensive audit rules
  template:
    src: audit.rules.j2
    dest: /etc/audit/rules.d/audit.rules
    backup: yes
  notify: restart auditd

- name: Initialize AIDE database
  command: aide --init
  args:
    creates: /var/lib/aide/aide.db.new.gz

- name: Move AIDE database to production location
  command: mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
  args:
    creates: /var/lib/aide/aide.db.gz

- name: Enable and start auditd service
  systemd:
    name: auditd
    enabled: yes
    state: started

Create comprehensive audit rules template

Define audit rules that cover critical security events including file access, privilege escalation, network connections, and system configuration changes.

# Delete all existing rules
-D

# Buffer size for audit events
-b 8192

# Failure mode (0=silent, 1=printk, 2=panic)
-f 1

# Monitor file access and modifications
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k privilege-escalation
-w /etc/sudoers.d/ -p wa -k privilege-escalation

# Monitor authentication and authorization
-w /var/log/auth.log -p wa -k authentication
-w /var/log/secure -p wa -k authentication
-w /etc/ssh/sshd_config -p wa -k ssh-config

# Monitor system configuration changes
-w /etc/hosts -p wa -k network-config
-w /etc/hostname -p wa -k network-config
-w /etc/resolv.conf -p wa -k network-config
-w /etc/crontab -p wa -k scheduled-tasks
-w /etc/cron.d/ -p wa -k scheduled-tasks

# Monitor critical system calls
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change
-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change
-a always,exit -F arch=b64 -S clock_settime -k time-change
-a always,exit -F arch=b32 -S clock_settime -k time-change

# Monitor network connections
-a always,exit -F arch=b64 -S socket -F a0=10 -k network-socket
-a always,exit -F arch=b64 -S socket -F a0=2 -k network-socket

# Monitor file permission changes
-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -k file-permissions
-a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -k file-ownership

# Monitor privilege escalation
-a always,exit -F arch=b64 -S setuid -S setgid -S setreuid -S setregid -k privilege-escalation

# Monitor kernel module loading
-w /sbin/insmod -p x -k kernel-modules
-w /sbin/rmmod -p x -k kernel-modules
-w /sbin/modprobe -p x -k kernel-modules

# Make rules immutable
-e 2

Create compliance checking role

Build an Ansible role that performs automated compliance checks against security frameworks like CIS benchmarks and generates structured results.

---
- name: Create compliance report directory
  file:
    path: /var/log/compliance
    state: directory
    mode: '0750'
    owner: root
    group: root

- name: Check SSH configuration compliance
  block:
    - name: Verify SSH protocol version
      lineinfile:
        path: /etc/ssh/sshd_config
        regexp: '^Protocol'
        line: 'Protocol 2'
        state: present
      check_mode: yes
      register: ssh_protocol_check
      failed_when: false

    - name: Check SSH root login disabled
      lineinfile:
        path: /etc/ssh/sshd_config
        regexp: '^PermitRootLogin'
        line: 'PermitRootLogin no'
        state: present
      check_mode: yes
      register: ssh_root_check
      failed_when: false

    - name: Verify SSH key authentication
      lineinfile:
        path: /etc/ssh/sshd_config
        regexp: '^PubkeyAuthentication'
        line: 'PubkeyAuthentication yes'
        state: present
      check_mode: yes
      register: ssh_pubkey_check
      failed_when: false

- name: Check file permission compliance
  stat:
    path: "{{ item.path }}"
  register: file_permissions
  loop:
    - { path: '/etc/passwd', expected: '0644' }
    - { path: '/etc/shadow', expected: '0640' }
    - { path: '/etc/group', expected: '0644' }
    - { path: '/etc/sudoers', expected: '0440' }

- name: Run AIDE file integrity check
  command: aide --check
  register: aide_check
  failed_when: false
  changed_when: false

- name: Check for rootkits with rkhunter
  command: rkhunter --check --skip-keypress --report-warnings-only
  register: rkhunter_check
  failed_when: false
  changed_when: false

- name: Generate compliance report
  template:
    src: compliance-report.j2
    dest: "/var/log/compliance/compliance-{{ ansible_date_time.date }}.json"
    mode: '0644'
  vars:
    compliance_results:
      ssh_protocol: "{{ ssh_protocol_check }}"
      ssh_root_login: "{{ ssh_root_check }}"
      ssh_pubkey_auth: "{{ ssh_pubkey_check }}"
      file_permissions: "{{ file_permissions }}"
      aide_check: "{{ aide_check }}"
      rkhunter_results: "{{ rkhunter_check }}"
      timestamp: "{{ ansible_date_time.iso8601 }}"
      hostname: "{{ ansible_hostname }}"
      ip_address: "{{ ansible_default_ipv4.address }}"

Create security hardening role

Implement automated security hardening based on industry standards. This role enforces security policies and configurations across your infrastructure.

---
- name: Configure password policies
  block:
    - name: Set password minimum length
      lineinfile:
        path: /etc/login.defs
        regexp: '^PASS_MIN_LEN'
        line: 'PASS_MIN_LEN 12'
        backup: yes

    - name: Set password maximum age
      lineinfile:
        path: /etc/login.defs
        regexp: '^PASS_MAX_DAYS'
        line: 'PASS_MAX_DAYS 90'
        backup: yes

    - name: Set password minimum age
      lineinfile:
        path: /etc/login.defs
        regexp: '^PASS_MIN_DAYS'
        line: 'PASS_MIN_DAYS 1'
        backup: yes

- name: Configure kernel parameters for security
  sysctl:
    name: "{{ item.name }}"
    value: "{{ item.value }}"
    state: present
    reload: yes
  loop:
    - { name: 'net.ipv4.ip_forward', value: '0' }
    - { name: 'net.ipv4.conf.all.send_redirects', value: '0' }
    - { name: 'net.ipv4.conf.default.send_redirects', value: '0' }
    - { name: 'net.ipv4.conf.all.accept_source_route', value: '0' }
    - { name: 'net.ipv4.conf.default.accept_source_route', value: '0' }
    - { name: 'net.ipv4.conf.all.accept_redirects', value: '0' }
    - { name: 'net.ipv4.conf.default.accept_redirects', value: '0' }
    - { name: 'net.ipv4.conf.all.log_martians', value: '1' }
    - { name: 'net.ipv4.conf.default.log_martians', value: '1' }
    - { name: 'kernel.randomize_va_space', value: '2' }

- name: Disable unnecessary services
  systemd:
    name: "{{ item }}"
    enabled: no
    state: stopped
  loop:
    - avahi-daemon
    - cups
    - bluetooth
  failed_when: false

- name: Configure file permissions for critical files
  file:
    path: "{{ item.path }}"
    mode: "{{ item.mode }}"
    owner: "{{ item.owner | default('root') }}"
    group: "{{ item.group | default('root') }}"
  loop:
    - { path: '/etc/passwd', mode: '0644' }
    - { path: '/etc/shadow', mode: '0640', group: 'shadow' }
    - { path: '/etc/group', mode: '0644' }
    - { path: '/etc/sudoers', mode: '0440' }
    - { path: '/boot/grub/grub.cfg', mode: '0600' }

- name: Configure fail2ban for SSH protection
  block:
    - name: Install fail2ban
      package:
        name: fail2ban
        state: present

    - name: Configure fail2ban SSH jail
      template:
        src: jail.local.j2
        dest: /etc/fail2ban/jail.local
        backup: yes
      notify: restart fail2ban

    - name: Enable and start fail2ban
      systemd:
        name: fail2ban
        enabled: yes
        state: started

Create automated reporting role

Build comprehensive reporting capabilities that aggregate compliance data, generate dashboards, and send alerts for security violations.

---
- name: Create reporting directories
  file:
    path: "{{ item }}"
    state: directory
    mode: '0755'
    owner: root
    group: root
  loop:
    - /var/log/compliance/reports
    - /var/log/compliance/alerts
    - /opt/compliance-dashboard

- name: Generate HTML compliance dashboard
  template:
    src: dashboard.html.j2
    dest: "/var/log/compliance/reports/compliance-dashboard-{{ ansible_date_time.date }}.html"
    mode: '0644'
  vars:
    report_date: "{{ ansible_date_time.date }}"
    total_hosts: "{{ groups['all'] | length }}"

- name: Create compliance summary report
  template:
    src: summary-report.j2
    dest: "/var/log/compliance/reports/summary-{{ ansible_date_time.date }}.json"
    mode: '0644'
  vars:
    compliance_summary:
      report_date: "{{ ansible_date_time.iso8601 }}"
      total_checks: 15
      passed_checks: "{{ compliance_passed | default(0) }}"
      failed_checks: "{{ compliance_failed | default(0) }}"
      hostname: "{{ ansible_hostname }}"
      ip_address: "{{ ansible_default_ipv4.address }}"

- name: Check for critical compliance failures
  set_fact:
    critical_failures: true
  when: >
    (ssh_root_check.changed | default(false)) or
    (aide_check.rc | default(0) != 0) or
    (rkhunter_check.rc | default(0) != 0)

- name: Send alert for critical failures
  mail:
    to: "{{ compliance_email | default('admin@example.com') }}"
    subject: "CRITICAL: Compliance failure on {{ ansible_hostname }}"
    body: |
      Critical compliance failures detected on {{ ansible_hostname }} ({{ ansible_default_ipv4.address }})
      
      Time: {{ ansible_date_time.iso8601 }}
      
      Failures detected:
      {% if ssh_root_check.changed | default(false) %}
      - SSH root login not properly disabled
      {% endif %}
      {% if aide_check.rc | default(0) != 0 %}
      - AIDE file integrity check failed
      {% endif %}
      {% if rkhunter_check.rc | default(0) != 0 %}
      - Rootkit scanner detected issues
      {% endif %}
      
      Please investigate immediately.
  when: critical_failures | default(false)
  ignore_errors: yes

- name: Generate audit log analysis
  shell: |
    ausearch -ts today | aureport -au > /var/log/compliance/reports/audit-summary-{{ ansible_date_time.date }}.txt
    ausearch -ts today | aureport -f >> /var/log/compliance/reports/audit-summary-{{ ansible_date_time.date }}.txt
  ignore_errors: yes

- name: Collect system security metrics
  shell: |
    echo "Security Metrics Report - {{ ansible_date_time.iso8601 }}" > /var/log/compliance/reports/security-metrics-{{ ansible_date_time.date }}.txt
    echo "========================================" >> /var/log/compliance/reports/security-metrics-{{ ansible_date_time.date }}.txt
    echo "Failed login attempts:" >> /var/log/compliance/reports/security-metrics-{{ ansible_date_time.date }}.txt
    grep "Failed password" /var/log/auth.log | wc -l >> /var/log/compliance/reports/security-metrics-{{ ansible_date_time.date }}.txt
    echo "Successful sudo commands:" >> /var/log/compliance/reports/security-metrics-{{ ansible_date_time.date }}.txt
    grep "sudo:" /var/log/auth.log | grep "COMMAND" | wc -l >> /var/log/compliance/reports/security-metrics-{{ ansible_date_time.date }}.txt
  ignore_errors: yes

Create main compliance playbook

Combine all roles into a comprehensive playbook that orchestrates the entire compliance automation workflow across your infrastructure.

---
- name: Automated Security Audit and Compliance
  hosts: all
  become: yes
  gather_facts: yes
  
  vars:
    compliance_email: "security@example.com"
    compliance_schedule: "daily"
    retention_days: 30
    
  pre_tasks:
    - name: Create timestamp for this run
      set_fact:
        compliance_run_id: "{{ ansible_date_time.epoch }}"
        
  roles:
    - role: audit-setup
      tags: ['setup', 'audit']
      
    - role: security-hardening
      tags: ['hardening', 'security']
      
    - role: compliance-check
      tags: ['compliance', 'check']
      
    - role: reporting
      tags: ['reporting', 'alerts']
      
  post_tasks:
    - name: Cleanup old compliance reports
      find:
        paths: /var/log/compliance/reports
        age: "{{ retention_days }}d"
        file_type: file
      register: old_reports
      
    - name: Remove old reports
      file:
        path: "{{ item.path }}"
        state: absent
      loop: "{{ old_reports.files }}"
      
    - name: Log compliance run completion
      lineinfile:
        path: /var/log/compliance/compliance.log
        line: "{{ ansible_date_time.iso8601 }} - Compliance run {{ compliance_run_id }} completed on {{ ansible_hostname }}"
        create: yes
        mode: '0644'

- name: Generate consolidated compliance report
  hosts: localhost
  gather_facts: no
  
  tasks:
    - name: Create consolidated report directory
      file:
        path: /opt/compliance-reports
        state: directory
        mode: '0755'
        
    - name: Generate infrastructure-wide compliance summary
      template:
        src: templates/infrastructure-summary.j2
        dest: "/opt/compliance-reports/infrastructure-compliance-{{ ansible_date_time.date }}.html"
        mode: '0644'
      vars:
        total_servers: "{{ groups['all'] | length }}"
        report_timestamp: "{{ ansible_date_time.iso8601 }}"
        
  tags: ['reporting', 'summary']

Create inventory and configuration

Set up your Ansible inventory with proper grouping and configure automation scheduling for regular compliance checks.

all:
  children:
    production:
      hosts:
        web-01:
          ansible_host: 203.0.113.10
          compliance_level: high
        web-02:
          ansible_host: 203.0.113.11
          compliance_level: high
        db-01:
          ansible_host: 203.0.113.20
          compliance_level: critical
          
    staging:
      hosts:
        staging-01:
          ansible_host: 203.0.113.50
          compliance_level: medium
          
    development:
      hosts:
        dev-01:
          ansible_host: 203.0.113.60
          compliance_level: low
          
  vars:
    ansible_user: ubuntu
    ansible_ssh_private_key_file: ~/.ssh/compliance-key
    compliance_email: security-team@example.com
    report_retention_days: 90

Configure automated scheduling

Set up cron jobs and systemd timers to run compliance checks automatically and ensure continuous monitoring of your infrastructure.

# Create systemd service for compliance checks
sudo tee /etc/systemd/system/audit-compliance.service > /dev/null << 'EOF'
[Unit]
Description=Automated Security Audit and Compliance Check
After=network.target

[Service]
Type=oneshot
User=root
WorkingDirectory=/opt/audit-compliance
ExecStart=/usr/bin/ansible-playbook -i inventory/hosts.yml playbooks/audit-compliance.yml
StandardOutput=journal
StandardError=journal
EOF

# Create systemd timer for daily execution
sudo tee /etc/systemd/system/audit-compliance.timer > /dev/null << 'EOF'
[Unit]
Description=Run audit compliance check daily
Requires=audit-compliance.service

[Timer]
OnCalendar=daily
Persistent=true
R

Automated install script

Run this to automate the entire setup

Nie chcesz zarządzać tym samodzielnie?

Zarządzamy infrastrukturą firm, które zależą od dostępności. W pełni zarządzana, z jednym stałym kontaktem, który zna Twoje środowisko.

Macie jednego stałego opiekuna, który zna Waszą konfigurację

Rotterdam 05:29 · dostępny w wiadomości, bez formularza zgłoszeń