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
RAutomated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Global variables
INSTALL_DIR="/opt/audit-compliance"
SCRIPT_USER="${SUDO_USER:-$(whoami)}"
# Error handling
cleanup() {
echo -e "${RED}[ERROR] Installation failed. Cleaning up...${NC}"
rm -rf "$INSTALL_DIR" 2>/dev/null || true
}
trap cleanup ERR
# Helper functions
log_info() { echo -e "${GREEN}$1${NC}"; }
log_warn() { echo -e "${YELLOW}$1${NC}"; }
log_error() { echo -e "${RED}$1${NC}"; }
usage() {
echo "Usage: $0 [OPTIONS]"
echo "Options:"
echo " -h, --help Show this help message"
echo " --no-verify Skip verification checks"
exit 1
}
check_root() {
if [[ $EUID -ne 0 ]]; then
log_error "This script must be run as root or with sudo"
exit 1
fi
}
detect_distro() {
if [ ! -f /etc/os-release ]; then
log_error "/etc/os-release not found. Cannot detect distribution."
exit 1
fi
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
;;
*)
log_error "Unsupported distribution: $ID"
exit 1
;;
esac
export PKG_MGR PKG_INSTALL PKG_UPDATE
}
install_packages() {
log_info "[2/8] Installing required packages..."
if [[ "$PKG_MGR" == "apt" ]]; then
$PKG_UPDATE
$PKG_INSTALL auditd audispd-plugins aide rkhunter chkrootkit ansible
else
$PKG_INSTALL audit audit-libs aide rkhunter chkrootkit ansible
fi
}
create_directory_structure() {
log_info "[3/8] Creating directory structure..."
mkdir -p "$INSTALL_DIR"/{playbooks,roles,inventory,reports,templates}
mkdir -p "$INSTALL_DIR"/roles/{audit-setup,compliance-check,security-hardening,reporting}/{tasks,templates,handlers,vars}
chown -R root:root "$INSTALL_DIR"
chmod -R 755 "$INSTALL_DIR"
}
create_ansible_config() {
log_info "[4/8] Creating Ansible configuration..."
cat > "$INSTALL_DIR/ansible.cfg" << 'EOF'
[defaults]
inventory = inventory/hosts
host_key_checking = False
gathering = smart
fact_caching = memory
retry_files_enabled = False
stdout_callback = yaml
bin_ansible_callbacks = True
[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False
EOF
chmod 644 "$INSTALL_DIR/ansible.cfg"
}
create_audit_role() {
log_info "[5/8] Creating audit setup role..."
cat > "$INSTALL_DIR/roles/audit-setup/tasks/main.yml" << 'EOF'
---
- name: Install audit packages
package:
name:
- "{{ 'auditd' if ansible_os_family == 'Debian' else 'audit' }}"
- "{{ 'audispd-plugins' if ansible_os_family == 'Debian' else 'audit-libs' }}"
- aide
state: present
- name: Configure auditd main configuration
template:
src: auditd.conf.j2
dest: /etc/audit/auditd.conf
backup: yes
mode: '0640'
owner: root
group: root
notify: restart auditd
- name: Deploy comprehensive audit rules
template:
src: audit.rules.j2
dest: /etc/audit/rules.d/audit.rules
backup: yes
mode: '0640'
owner: root
group: root
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
EOF
cat > "$INSTALL_DIR/roles/audit-setup/templates/auditd.conf.j2" << 'EOF'
log_file = /var/log/audit/audit.log
log_format = RAW
log_group = adm
priority_boost = 4
flush = INCREMENTAL_ASYNC
freq = 50
num_logs = 5
disp_qos = lossy
dispatcher = /sbin/audispd
name_format = HOSTNAME
max_log_file = 50
max_log_file_action = ROTATE
space_left = 75
space_left_action = SYSLOG
admin_space_left = 50
admin_space_left_action = SUSPEND
disk_full_action = SUSPEND
disk_error_action = SUSPEND
use_libwrap = yes
tcp_listen_queue = 5
tcp_max_per_addr = 1
tcp_client_max_idle = 0
enable_krb5 = no
krb5_principal = auditd
EOF
cat > "$INSTALL_DIR/roles/audit-setup/templates/audit.rules.j2" << 'EOF'
-D
-b 8192
-f 1
-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
-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
-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
-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
-e 2
EOF
cat > "$INSTALL_DIR/roles/audit-setup/handlers/main.yml" << 'EOF'
---
- name: restart auditd
systemd:
name: auditd
state: restarted
EOF
}
create_compliance_playbook() {
log_info "[6/8] Creating compliance playbook..."
cat > "$INSTALL_DIR/playbooks/compliance-audit.yml" << 'EOF'
---
- name: Configure Audit Compliance Automation
hosts: all
become: yes
roles:
- audit-setup
- compliance-check
- security-hardening
- reporting
EOF
cat > "$INSTALL_DIR/inventory/hosts" << 'EOF'
[audit-targets]
localhost ansible_connection=local
[audit-targets:vars]
ansible_python_interpreter=/usr/bin/python3
EOF
}
create_systemd_service() {
log_info "[7/8] Creating systemd service for automated compliance checks..."
cat > /etc/systemd/system/audit-compliance.service << EOF
[Unit]
Description=Audit Compliance Automation
After=network.target
[Service]
Type=oneshot
WorkingDirectory=$INSTALL_DIR
ExecStart=/usr/bin/ansible-playbook playbooks/compliance-audit.yml
User=root
Group=root
[Install]
WantedBy=multi-user.target
EOF
cat > /etc/systemd/system/audit-compliance.timer << 'EOF'
[Unit]
Description=Run audit compliance checks daily
Requires=audit-compliance.service
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable audit-compliance.timer
systemctl start audit-compliance.timer
chmod 644 /etc/systemd/system/audit-compliance.service
chmod 644 /etc/systemd/system/audit-compliance.timer
}
verify_installation() {
log_info "[8/8] Verifying installation..."
if ! systemctl is-active --quiet auditd; then
log_error "auditd service is not running"
return 1
fi
if [ ! -f /var/lib/aide/aide.db.gz ]; then
log_warn "AIDE database not found, this is normal on first run"
fi
if ! ansible --version &>/dev/null; then
log_error "Ansible installation failed"
return 1
fi
if ! systemctl is-enabled --quiet audit-compliance.timer; then
log_error "Compliance automation timer not enabled"
return 1
fi
log_info "Installation completed successfully!"
log_info "Audit compliance automation is now configured and scheduled to run daily"
log_info "Configuration directory: $INSTALL_DIR"
log_info "Run manually with: cd $INSTALL_DIR && ansible-playbook playbooks/compliance-audit.yml"
}
main() {
local skip_verify=false
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help) usage ;;
--no-verify) skip_verify=true; shift ;;
*) log_error "Unknown option: $1"; usage ;;
esac
done
log_info "[1/8] Checking prerequisites..."
check_root
detect_distro
install_packages
create_directory_structure
create_ansible_config
create_audit_role
create_compliance_playbook
create_systemd_service
if [[ "$skip_verify" == false ]]; then
verify_installation
fi
}
main "$@"
Review the script before running. Execute with: bash install.sh