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.

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

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

Automate security compliance with Ansible. Implement CIS Benchmarks, DISA STIG, PCI DSS, and SOC 2 hardening across enterprise infrastructure at scale.

Introduction

Security compliance is not optional — regulations like PCI DSS, SOC 2, HIPAA, and government standards like CIS Benchmarks and DISA STIGs require organizations to maintain hardened configurations across their entire infrastructure. Doing this manually is impossible at scale. Ansible transforms compliance from a periodic audit nightmare into continuous, automated enforcement.

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

Compliance Frameworks

FrameworkScopeWho Needs It
CIS BenchmarksOS/app hardeningEveryone (best practice)
DISA STIGGovernment securityUS DoD, federal agencies
PCI DSSPayment card dataAnyone handling credit cards
SOC 2Service securitySaaS providers, cloud services
HIPAAHealth dataHealthcare organizations
NIST 800-53Security controlsUS federal information systems

Compliance as Code

The key principle: define compliance rules as Ansible playbooks, then enforce them continuously.

# compliance-baseline.yml
---
- name: Apply CIS Level 1 baseline
  hosts: all
  become: true
  roles:
    - cis_level1_filesystem
    - cis_level1_services
    - cis_level1_network
    - cis_level1_logging
    - cis_level1_access

CIS Benchmark Implementation

Filesystem Hardening

# CIS 1.1.1 — Disable unused filesystems
- name: "CIS 1.1.1.1 | Disable cramfs"
  ansible.builtin.copy:
    content: "install cramfs /bin/true\nblacklist cramfs\n"
    dest: /etc/modprobe.d/cramfs.conf
    mode: '0644'

- name: "CIS 1.1.1.2 | Disable freevxfs"
  ansible.builtin.copy:
    content: "install freevxfs /bin/true\nblacklist freevxfs\n"
    dest: /etc/modprobe.d/freevxfs.conf

# CIS 1.1.2 — /tmp on separate partition with noexec
- name: "CIS 1.1.2 | Ensure /tmp has noexec"
  ansible.posix.mount:
    name: /tmp
    src: "{{ tmp_device }}"
    fstype: tmpfs
    opts: defaults,noexec,nosuid,nodev
    state: mounted

Service Hardening

# CIS 2.1 — Disable unnecessary services
- name: "CIS 2.1 | Disable unneeded services"
  ansible.builtin.systemd:
    name: "{{ item }}"
    state: stopped
    enabled: false
    masked: true
  loop:
    - avahi-daemon
    - cups
    - rpcbind
    - nfs-server
    - vsftpd
    - xinetd
  ignore_errors: true  # Service may not be installed

# CIS 2.2 — Ensure time synchronization
- name: "CIS 2.2.1 | Ensure chrony is configured"
  ansible.builtin.template:
    src: chrony.conf.j2
    dest: /etc/chrony.conf
  notify: restart chronyd

SSH Hardening

# CIS 5.2 — SSH Server Configuration
- name: "CIS 5.2 | Harden SSH configuration"
  ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    regexp: "{{ item.regexp }}"
    line: "{{ item.line }}"
  loop:
    - { regexp: '^#?PermitRootLogin', line: 'PermitRootLogin no' }
    - { regexp: '^#?PasswordAuthentication', line: 'PasswordAuthentication no' }
    - { regexp: '^#?MaxAuthTries', line: 'MaxAuthTries 4' }
    - { regexp: '^#?ClientAliveInterval', line: 'ClientAliveInterval 300' }
    - { regexp: '^#?ClientAliveCountMax', line: 'ClientAliveCountMax 3' }
    - { regexp: '^#?LoginGraceTime', line: 'LoginGraceTime 60' }
    - { regexp: '^#?X11Forwarding', line: 'X11Forwarding no' }
    - { regexp: '^#?AllowTcpForwarding', line: 'AllowTcpForwarding no' }
    - { regexp: '^#?Protocol', line: 'Protocol 2' }
  notify: restart sshd

Audit Logging

# CIS 4.1 — Configure auditd
- name: "CIS 4.1.1 | Ensure auditd is installed"
  ansible.builtin.package:
    name:
      - audit
      - audit-libs
    state: present

- name: "CIS 4.1.2 | Configure audit rules"
  ansible.builtin.template:
    src: audit.rules.j2
    dest: /etc/audit/rules.d/cis.rules
  notify: restart auditd

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

DISA STIG Automation

# Use the RHEL STIG role from Ansible Galaxy
# ansible-galaxy install redhatofficial.rhel9_stig

- name: Apply DISA STIG to RHEL 9
  hosts: government_servers
  become: true
  vars:
    # Override specific controls
    rhel9stig_ssh_required: true
    rhel9stig_fips_required: true
    rhel9stig_aide_required: true
  roles:
    - redhatofficial.rhel9_stig

PCI DSS Requirements

# PCI DSS Requirement 2 — Change default passwords
- name: "PCI 2.1 | Ensure no default passwords"
  ansible.builtin.user:
    name: "{{ item }}"
    password_lock: true
  loop: "{{ default_accounts }}"

# PCI DSS Requirement 8 — Password policy
- name: "PCI 8.2 | Set password complexity"
  ansible.builtin.lineinfile:
    path: /etc/security/pwquality.conf
    regexp: "{{ item.regexp }}"
    line: "{{ item.line }}"
  loop:
    - { regexp: '^minlen', line: 'minlen = 12' }
    - { regexp: '^dcredit', line: 'dcredit = -1' }
    - { regexp: '^ucredit', line: 'ucredit = -1' }
    - { regexp: '^lcredit', line: 'lcredit = -1' }
    - { regexp: '^ocredit', line: 'ocredit = -1' }

# PCI DSS Requirement 10 — Logging
- name: "PCI 10.2 | Ensure audit logging"
  ansible.builtin.service:
    name: auditd
    state: started
    enabled: true

See also: Ansible Automation Platform RBAC: Role-Based Access Control for Enterprise Teams

Compliance Scanning (Audit Mode)

Run playbooks in check mode to audit without changing anything:

# Dry-run compliance check
ansible-playbook compliance-baseline.yml --check --diff

# Generate compliance report
ansible-playbook compliance-audit.yml -e "report_output=/tmp/compliance-report.html"

Audit Playbook Pattern

- name: Compliance audit
  hosts: all
  become: true
  tasks:
    - name: "Check SSH PermitRootLogin"
      ansible.builtin.command: grep "^PermitRootLogin no" /etc/ssh/sshd_config
      register: ssh_root
      changed_when: false
      failed_when: false

    - name: Record compliance status
      ansible.builtin.set_fact:
        compliance_results: "{{ compliance_results | default([]) + [
          {'control': 'SSH-001', 'name': 'PermitRootLogin', 'status': 'PASS' if ssh_root.rc == 0 else 'FAIL'}
        ] }}"

    - name: Generate report
      ansible.builtin.template:
        src: compliance-report.j2
        dest: "/tmp/compliance-{{ inventory_hostname }}.json"
      delegate_to: localhost

Continuous Compliance with AAP

# Schedule compliance checks in AAP:
# 1. Daily audit scan (check mode) → generates report
# 2. Weekly remediation run → enforces baseline
# 3. Alert on drift → notify security team

# Workflow Template:
# [Audit Scan] → [Diff Report] → [Approval Gate] → [Remediate]

Community Roles

# CIS Benchmark roles
ansible-galaxy install alivx.cis_ubuntu_22
ansible-galaxy install MindPointGroup.RHEL9-CIS

# STIG roles
ansible-galaxy install redhatofficial.rhel9_stig

# Hardening
ansible-galaxy install dev-sec.os-hardening
ansible-galaxy install dev-sec.ssh-hardening

Best Practices

  1. Start with check mode — Audit before enforcing to understand the gap
  2. Tag controls individually — Run specific controls: --tags "cis_5.2,cis_4.1"
  3. Environment-specific exceptions — Some controls may not apply to all systems
  4. Version your compliance code — Git-managed playbooks with change history
  5. Automate reporting — Generate machine-readable compliance reports (JSON/CSV)
  6. Schedule regular scans — Daily audits, weekly remediation in AAP
  7. Test in staging first — Compliance hardening can break applications
  8. Document exceptions — Track why specific controls are skipped

FAQ

Can Ansible replace a compliance scanner?

Ansible can enforce and audit configurations but may not replace dedicated scanners like OpenSCAP or Qualys for vulnerability assessment. They complement each other — Ansible remediates what scanners find.

How to handle exceptions?

Use variables to skip controls: cis_5_2_enabled: false. Document why in your compliance repository.

CIS Level 1 vs Level 2?

Level 1 is practical for most environments. Level 2 adds stricter controls that may impact usability (e.g., USB storage disabled, specific kernel parameters). Start with Level 1.

Conclusion

Ansible transforms compliance from a manual audit exercise into continuous automated enforcement. By codifying CIS Benchmarks, STIG, and PCI DSS requirements as playbooks, organizations can maintain compliance at scale while reducing the cost and effort of security audits.

Category: installation

Browse all Ansible tutorials · AnsiblePilot Home