AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

AAP 2.6 Compliance and Audit: CIS Benchmarks, STIG, and Regulatory Automation

By Luca Berton · Published 2024-01-01 · Category: installation

Automate compliance auditing and remediation with AAP 2.6. Implement CIS benchmarks, DISA STIGs, PCI-DSS, HIPAA, and SOX controls using Ansible playbooks.

Compliance Automation with AAP 2.6

Manual compliance auditing doesn't scale. AAP 2.6 enables continuous, automated compliance that:

  • Audits systems against security benchmarks (CIS, STIG, PCI-DSS)
  • Remediates non-compliant configurations automatically
  • Reports compliance status for auditors
  • Proves enforcement through audit trails and job logs

Compliance Frameworks

FrameworkFocusSectors
CIS BenchmarksSystem hardeningAll industries
DISA STIGDoD securityGovernment, defense
PCI-DSSPayment card dataRetail, finance
HIPAAHealthcare dataHealthcare
SOXFinancial reportingPublic companies
NIST 800-53Federal systemsGovernment
ISO 27001Information securityAll industries

CIS Benchmark Automation

Using the ansible-lockdown Collection

The community maintains CIS benchmark roles:

# requirements.yml
collections:
  - name: community.general
roles:
  - name: ansible-lockdown.rhel9_cis
    src: https://github.com/ansible-lockdown/RHEL9-CIS

CIS Hardening Playbook

---
- name: Apply CIS Level 1 hardening
  hosts: all
  become: true

  vars:
    # CIS Section 1 - Initial Setup
    rhel9cis_rule_1_1_1_1: true   # Disable cramfs
    rhel9cis_rule_1_1_1_2: true   # Disable freevxfs
    rhel9cis_rule_1_1_1_3: true   # Disable jffs2
    rhel9cis_rule_1_1_1_4: true   # Disable hfs
    rhel9cis_rule_1_1_1_5: true   # Disable hfsplus
    rhel9cis_rule_1_1_1_6: true   # Disable squashfs
    rhel9cis_rule_1_1_1_7: true   # Disable udf

    # CIS Section 5 - Access, Authentication and Authorization
    rhel9cis_rule_5_2_1: true     # Configure SSH Protocol
    rhel9cis_rule_5_2_4: true     # Disable SSH X11 forwarding
    rhel9cis_rule_5_2_5: true     # Set SSH MaxAuthTries
    rhel9cis_rule_5_2_11: true    # Set SSH LoginGraceTime
    rhel9cis_ssh_maxsessions: 4

    # CIS Section 6 - System Maintenance
    rhel9cis_rule_6_1_1: true     # Audit system file permissions

  tasks:
    - name: Gather compliance baseline
      ansible.builtin.setup:
        gather_subset:
          - hardware
          - network

    - name: Apply CIS hardening
      ansible.builtin.include_role:
        name: ansible-lockdown.rhel9_cis

    - name: Generate compliance report
      ansible.builtin.template:
        src: cis-report.j2
        dest: "/var/reports/cis/{{ inventory_hostname }}_{{ ansible_date_time.date }}.html"
      delegate_to: localhost

Custom CIS Controls

- name: CIS 1.4.1 - Ensure permissions on bootloader config
  ansible.builtin.file:
    path: /boot/grub2/grub.cfg
    owner: root
    group: root
    mode: '0600'
  tags: [cis, cis_1_4_1, level1]

- name: CIS 5.2.2 - Ensure SSH access is limited
  ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^AllowGroups'
    line: 'AllowGroups sshusers'
    validate: '/usr/sbin/sshd -t -f %s'
  notify: restart sshd
  tags: [cis, cis_5_2_2, level1]

- name: CIS 5.4.1 - Ensure password creation requirements
  community.general.pam_limits:
    domain: '*'
    limit_type: '-'
    limit_item: maxlogins
    value: '10'
  tags: [cis, cis_5_4_1, level1]

- name: CIS 4.2.1.4 - Ensure rsyslog default file permissions
  ansible.builtin.lineinfile:
    path: /etc/rsyslog.conf
    regexp: '^\$FileCreateMode'
    line: '$FileCreateMode 0640'
  notify: restart rsyslog
  tags: [cis, cis_4_2_1_4, level1]

See also: Ansible for Compliance Automation: CIS Benchmarks, STIG, and PCI DSS

DISA STIG Automation

OpenSCAP Integration

- name: Run STIG compliance scan
  hosts: all
  become: true

  tasks:
    - name: Install OpenSCAP
      ansible.builtin.dnf:
        name:
          - openscap-scanner
          - scap-security-guide
        state: present

    - name: Run STIG scan
      ansible.builtin.command:
        cmd: >
          oscap xccdf eval
          --profile xccdf_org.ssgproject.content_profile_stig
          --results /tmp/stig-results.xml
          --report /tmp/stig-report.html
          /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml
      register: scan_result
      failed_when: false
      changed_when: false

    - name: Fetch STIG report
      ansible.builtin.fetch:
        src: /tmp/stig-report.html
        dest: "reports/stig/{{ inventory_hostname }}_stig.html"
        flat: true

    - name: Parse STIG results
      ansible.builtin.command:
        cmd: >
          oscap xccdf generate report
          --output /tmp/stig-summary.txt
          /tmp/stig-results.xml
      changed_when: false

    - name: Check pass rate
      ansible.builtin.shell: |
        grep -c 'pass' /tmp/stig-results.xml
      register: pass_count
      changed_when: false

    - name: Report compliance score
      ansible.builtin.debug:
        msg: "STIG compliance: {{ pass_count.stdout }} rules passing on {{ inventory_hostname }}"

Automated STIG Remediation

- name: STIG remediation
  hosts: all
  become: true

  tasks:
    - name: Run OpenSCAP remediation
      ansible.builtin.command:
        cmd: >
          oscap xccdf eval
          --profile xccdf_org.ssgproject.content_profile_stig
          --remediate
          --results /tmp/stig-remediation-results.xml
          /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml
      register: remediation
      failed_when: false

PCI-DSS Compliance

Key PCI-DSS Controls as Playbooks

- name: PCI-DSS automated controls
  hosts: pci_scope
  become: true

  tasks:
    # Requirement 2: Do not use vendor-supplied defaults
    - name: PCI 2.1 - Change default passwords
      ansible.builtin.user:
        name: "{{ item }}"
        password: "{{ vault_passwords[item] | password_hash('sha512') }}"
      loop: "{{ default_accounts }}"
      no_log: true
      tags: [pci, pci_2_1]

    # Requirement 8: Identify and authenticate access
    - name: PCI 8.2 - Enforce password complexity
      ansible.builtin.template:
        src: pwquality.conf.j2
        dest: /etc/security/pwquality.conf
        mode: '0644'
      tags: [pci, pci_8_2]

    # Requirement 10: Track and monitor access
    - name: PCI 10.1 - Enable audit logging
      ansible.builtin.service:
        name: auditd
        state: started
        enabled: true
      tags: [pci, pci_10_1]

    - name: PCI 10.2 - Configure audit rules
      ansible.builtin.template:
        src: audit.rules.j2
        dest: /etc/audit/rules.d/pci-dss.rules
        mode: '0640'
      notify: restart auditd
      tags: [pci, pci_10_2]

    # Requirement 11: Test security systems
    - name: PCI 11.5 - File integrity monitoring
      ansible.builtin.dnf:
        name: aide
        state: present
      tags: [pci, pci_11_5]

    - name: Initialize AIDE database
      ansible.builtin.command:
        cmd: aide --init
        creates: /var/lib/aide/aide.db.new.gz
      tags: [pci, pci_11_5]

See also: Ansible for Financial Services: Compliance, Trading Systems, and Regulatory Automation

Compliance Workflows in AAP

Continuous Compliance Pipeline

[Inventory Sync] → [Compliance Scan]
                        ↓
              ┌─────────┼─────────┐
              │         │         │
        [CIS Scan] [STIG Scan] [PCI Scan]
              │         │         │
              └─────────┼─────────┘
                        ↓
              [Generate Reports]
                   ↓ all pass          ↓ failures
          [Update CMDB]        [Auto-Remediate]
                                       ↓
                               [Re-Scan]
                                   ↓ pass         ↓ fail
                          [Close Ticket]    [Escalate to Security]

Schedule Compliance Scans

- name: Schedule weekly compliance scan
  ansible.platform.schedule:
    controller_host: "{{ gateway_url }}"
    controller_username: "{{ controller_user }}"
    controller_password: "{{ controller_pass }}"
    name: "Weekly Compliance Audit"
    unified_job_template: "Full Compliance Scan"
    rrule: "DTSTART:20260101T060000Z RRULE:FREQ=WEEKLY;BYDAY=MO"
    extra_data:
      scan_type: full
      remediate: false
      email_report: true
    state: present

- name: Schedule daily quick check
  ansible.platform.schedule:
    name: "Daily Compliance Quick Check"
    unified_job_template: "Compliance Quick Scan"
    rrule: "DTSTART:20260101T050000Z RRULE:FREQ=DAILY"
    extra_data:
      scan_type: quick
      check_critical_only: true
    state: present

Compliance Reporting

Structured Compliance Report

- name: Generate compliance dashboard data
  hosts: all
  become: true
  gather_facts: true

  tasks:
    - name: Run compliance checks
      ansible.builtin.include_tasks: checks/{{ item }}.yml
      loop:
        - password_policy
        - ssh_config
        - firewall_rules
        - file_permissions
        - service_status
        - patch_level
      register: compliance_checks

    - name: Export results as JSON
      ansible.builtin.set_stats:
        data:
          compliance_results:
            hostname: "{{ inventory_hostname }}"
            timestamp: "{{ ansible_date_time.iso8601 }}"
            os: "{{ ansible_distribution }} {{ ansible_distribution_version }}"
            checks_passed: "{{ compliance_checks | selectattr('failed', 'false') | list | length }}"
            checks_failed: "{{ compliance_checks | selectattr('failed', 'true') | list | length }}"
            score: "{{ (compliance_checks | selectattr('failed', 'false') | list | length / compliance_checks | length * 100) | round(1) }}%"

See also: Ansible Zero Trust Security: Implement Zero Trust Architecture for Enterprise Infrastructure

AAP Audit Trail

AAP itself provides an audit trail for compliance:

Activity Stream

# Who ran what, when
curl -s -k -H "Authorization: Bearer $TOKEN" \
  "https://gateway.example.org/api/controller/v2/activity_stream/?order_by=-timestamp&page_size=20" | \
  jq '.results[] | {
    timestamp: .timestamp,
    user: .summary_fields.actor.username,
    action: .operation,
    resource_type: .object1,
    resource_name: .summary_fields.object1.name
  }'

Job-Level Audit

Every AAP job stores:

  • Who launched it (user, team)
  • What was run (playbook, template, extra vars)
  • When it started and finished
  • Where it ran (inventory, hosts, execution node)
  • Results (stdout, changed/failed tasks)
This built-in audit capability satisfies many compliance requirements without additional tooling.

FAQ

Can AAP replace dedicated compliance tools like Qualys or Tenable?

AAP complements rather than replaces vulnerability scanners. Use Qualys/Tenable for vulnerability discovery and AAP for remediation. AAP excels at configuration compliance (CIS, STIG) while scanners excel at CVE detection.

How do I handle exceptions and waivers?

Use Ansible variables to control which checks apply to which hosts. Create a compliance_waivers dictionary that skips specific checks for specific hosts, with documented justification stored in version control.

Can I generate compliance reports for auditors?

Yes. Use Jinja2 templates to generate HTML/PDF reports from scan results. Schedule report generation as part of your compliance workflow. AAP's job logs themselves serve as evidence of automation enforcement.

How often should compliance scans run?

Run critical checks daily, full scans weekly, and comprehensive audits monthly. Use EDA to trigger immediate scans after configuration changes. Continuous compliance is better than periodic auditing.

Does the AAP audit log meet SOX requirements?

AAP's Activity Stream provides who/what/when/where for every automation action, which addresses many SOX IT general controls. For full SOX compliance, integrate AAP logs with your SIEM and ensure proper access controls are in place for the AAP platform itself.

Conclusion

Compliance automation with AAP 2.6 transforms security from a periodic audit event into a continuous, automated process. By codifying compliance standards as Ansible playbooks, you achieve consistent enforcement, instant remediation, and comprehensive audit trails that satisfy regulators and reduce risk.

Category: installation

Browse all Ansible tutorials · AnsiblePilot Home