Why Automate Compliance?

Compliance Automation

Manual compliance is slow, error-prone, and unsustainable. Automation provides continuous verification, instant reporting, and faster audit cycles.

CIS Benchmark Scanning

Automate CIS benchmark checks across infrastructure:

cis-benchmark-config.yaml

benchmarks:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- name: "CIS AWS Foundations Benchmark v3.0"

scope: "account"

checks:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- id: "1.1"

title: "Avoid using root account"

command: "aws iam get-account-summary | jq '.SummaryMap.AccountAccessKeysPresent'"

expected: "0"

severity: "critical"

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- id: "1.3"

title: "Ensure MFA for root account"

command: "aws iam get-account-summary | jq '.SummaryMap.AccountMFAEnabled'"

expected: "1"

severity: "critical"

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- id: "2.1"

title: "Enable CloudTrail in all regions"

command: "aws cloudtrail describe-trails --query 'trailList[*].IsMultiRegionTrail'"

expected: "[true]"

severity: "high"

CIS compliance checker

import subprocess

import json

class CISChecker:

def init(self, config):

self.checks = config["checks"]

self.results = []

def run_checks(self):

for check in self.checks:

result = self.run_single_check(check)

self.results.append(result)

return self.generate_report()

def run_single_check(self, check):

try:

output = subprocess.check_output(

check["command"], shell=True, text=True

).strip()

passed = output == check["expected"]

return {

"id": check["id"],

"title": check["title"],

"passed": passed,

"severity": check["severity"],

"actual": output,

"expected": check["expected"]

}

except subprocess.CalledProcessError:

return {

"id": check["id"],

"title": check["title"],

"passed": False,

"severity": check["severity"],

"error": "Command failed"

}

Automated Remediation

def auto_remediate(findings):

remediations = {

"s3_public_access": lambda: boto3.client("s3control")

.put_public_access_block(

AccountId=ACCOUNT_ID,

PublicAccessBlockConfiguration={

"BlockPublicAcls": True,

"IgnorePublicAcls": True,

"BlockPublicPolicy": True,

"RestrictPublicBuckets": True

}

),

"unencrypted_ebs": lambda volume_id:

boto3.client("ec2").modify_volume(

VolumeId=volume_id,

Encrypted=True

),

"cloudtrail_disabled": lambda region:

boto3.client("cloudtrail").create_trail(

Name="automated-compliance-trail",

S3BucketName="compliance-logs-bucket",

IsMultiRegionTrail=True,

EnableLogFileValidation=True

)

}

for finding in findings:

if finding["auto_remediable"] and finding["severity"] == "critical":

action = remediations.get(finding["type"])

if action:

action()

finding["remediated"] = True

Compliance Reporting

Generate auditor-ready reports:

from jinja2 import Template

import markdown

def generate_compliance_report(results, framework="CIS AWS v3.0"):

summary = {

"framework": framework,

"timestamp": datetime.utcnow().isoformat(),

"total_checks": len(results),

"passed": sum(1 for r in results if r["passed"]),

"failed": sum(1 for r in results if not r["passed"]),

"compliance_score": sum(1 for r in results if r["passed"]) / len(results) * 100

}

report_md = f"""

Compliance Report: {framework}

Date: {summary['timestamp']}

Score: {summary['compliance_score']:.1f}%

Summary

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- Total Checks: {summary['total_checks']}

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- Passed: {summary['passed']}

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- Failed: {summary['failed']}

Failed Controls

"""

for result in results:

if not result["passed"]:

report_md += f"""

{result['id']}: {result['title']}

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- Severity: {result['severity']}

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- Expected: {result['expected']}

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- Actual: {result.get('actual', 'N/A')}

"""

return markdown.markdown(report_md)

Continuous Monitoring

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\-- Compliance monitoring dashboard

CREATE VIEW compliance_dashboard AS

SELECT

framework,

account_id,

COUNT(*) as total_controls,

SUM(CASE WHEN status = 'passed' THEN 1 ELSE 0 END) as passed,

SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed,

ROUND(AVG(CASE WHEN status = 'passed' THEN 100.0 ELSE 0.0 END), 1) as score,

MAX(checked_at) as last_checked

FROM compliance_checks

WHERE checked_at > NOW() - INTERVAL '24 hours'

GROUP BY framework, account_id;

Conclusion

Automate compliance with CIS benchmark scanning, remediation, reporting, and monitoring. Start with critical controls and expand coverage gradually. Use infrastructure-as-code to enforce compliance at deploy time. Continuously monitor compliance posture and alert on drift. Automation turns compliance from a periodic burden into a continuous assurance program.