Your auditor sends a request list. Item 14: "Provide evidence that S3 logging was enabled for all storage in scope during the audit period." You know the compliance.tf module enforces this. The auditor does not want to read module source code.
The gap between "controls are enforced in the module" and "we can prove it to an auditor" is what verification solves. This article covers both: how to confirm compliance.tf modules are working as described, and how to produce the artifacts auditors accept.
Terminology
As with all compliance.tf content, "Terraform" here includes OpenTofu. Both are fully supported.
Where Compliance.tf Fits With Scanning Tools
Security scanners fall into two categories based on when they run:
- IaC scanners (pre-apply). Tools like Checkov and Trivy analyze Terraform source code and plan files before changes are applied. They catch misconfigurations in your code but cannot verify what is actually running in AWS.
- Infrastructure scanners (post-apply). Tools like Powerpipe, Prowler, and AWS Config query actual AWS resources via API. They verify the real state of your environment after resources are deployed.
Prowler has added IaC scanning via Trivy integration, making it a hybrid tool that can participate in both stages.
Compliance.tf enforces controls inside the module code, making high-impact misconfigurations structurally impossible to apply. Scanners then confirm the guardrails are effective:
- Pre-apply. IaC scanners validate your Terraform plan before anything is created or updated.
- Post-apply. Infrastructure scanners verify that deployed resources match expected configurations.
Think of compliance.tf modules as the preventive layer and scanners as independent verification. See which modules are available and the controls they enforce.
A Typical Verification Flow
Verification runs at two stages: before you apply infrastructure changes, and after resources exist in AWS.
Pre-Apply: IaC Scanning
-
Generate a Terraform plan
bashterraform init terraform plan -out=plan.out terraform show -json plan.out > plan.jsonplan.jsonis the artifact you feed into IaC scanners. -
Run IaC scanners against the plan
bashcheckov -f plan.json trivy config plan.jsonWith compliance.tf modules, most controls pass automatically because the modules enforce compliant configurations internally. When a check fails, the scanner reports the finding with remediation guidance. Fix the configuration, regenerate the plan, run again.
A typical Checkov JSON result for a passing control looks like this:
json{ "check_id": "CKV_AWS_18", "check_type": "terraform_plan", "resource": "module.s3_bucket.aws_s3_bucket.this[0]", "check_result": { "result": "PASSED" }, "file_path": "plan.json" }Auditors can receive these JSON reports directly or import them into GRC platforms that accept scan output.
-
Integrate in CI
Add IaC scanning to your pipeline so every pull request is validated before merge. Non-compliant configurations are blocked before
terraform apply.
Post-Apply: Infrastructure Scanning
-
Deploy infrastructure
After
terraform apply, resources exist in your AWS account. -
Run infrastructure scanners
bashpowerpipe control run aws_compliance.benchmark.cis_v300 prowler aws --compliance cis_3.0_awsThese tools verify the real state — catching drift and resources created outside Terraform.
-
Schedule regular scans
Run infrastructure scans on a schedule (daily or weekly) to detect drift and resources not managed by compliance.tf modules.
The goal is not to replace your existing process. Compliance.tf modules block misconfigurations at plan time, IaC scanners confirm the plan is clean, and infrastructure scanners verify the deployed state.
Example: Proving S3 Logging Is Always On
The s3_bucket_logging_enabled control maps to SOC 2 CC7.2, PCI DSS v4.0 (10.2.1), and CIS AWS v6.0 (3.3).
In the first article, we showed how compliance.tf prevents attempts to disable S3 logging inside a module. Here is how verification makes that visible at each stage.
Pre-apply
- A developer writes Terraform using the S3 bucket module from compliance.tf.
- Checkov or Trivy scans the plan file and confirms logging is configured.
- Even if the developer passed
logging = {}, the compliance.tf module enforces the requirement — the plan fails untillogging.target_bucketis specified.
Post-apply
- After
terraform apply, the S3 bucket exists in AWS. - Powerpipe or Prowler queries the actual bucket and confirms logging is enabled.
- If someone creates a misconfigured bucket outside of compliance.tf, the infrastructure scanner flags it as non-compliant.
The combination — "the module cannot skip logging" plus "independent scanners confirm logging is on at both stages" — gives you a defensible position with auditors.
What Evidence Auditors Actually Need
Auditors do not read Terraform code. They need repeatable artifacts that show controls were active during the audit period.
Pre-apply scan reports. IaC scanner output from CI showing that every Terraform plan was validated before deployment. These export from your CI system as JSON or HTML.
Post-apply validation reports. Infrastructure scanner reports from Powerpipe, Prowler, or AWS Config showing which controls passed or failed for each account, region, or environment. Powerpipe benchmark results and AWS Config conformance pack results can be imported as custom evidence into GRC platforms like Vanta, Drata, and Sprinto.
Module documentation with control mappings. Each compliance.tf module documents which framework controls it implements. The s3_bucket_logging_enabled control page shows which modules enforce it and the framework clause IDs — SOC 2 CC7.2, PCI DSS v4.0 10.2.1, CIS AWS v6.0 3.3. That mapping is the bridge between "the module does X" and "the module satisfies clause Y."
Module version history. The changelog for each compliance.tf module version documents which controls were added, changed, or removed. Link this to your change management records during audits.
Exception documentation. Where exceptions are allowed, flags or alternate modules make them explicit. Validation reports show when and where these exceptions are active.
Putting It All Together
- Prevention. Compliance.tf modules make non-compliant configurations impossible to apply for the controls they cover.
- Pre-apply verification. IaC scanners confirm the Terraform plan is compliant before any resources are created.
- Post-apply verification. Infrastructure scanners confirm deployed resources match expectations and catch drift.
You keep your existing scanning tools and Terraform workflow. Compliance.tf modules carry compliance controls into every plan that uses them. Scanners provide independent confirmation at both stages.
If you want to see this in your own environment:
- Check the module catalog to see which AWS services currently have compliance controls.
- Review the controls and their framework clause mappings.
- Check the technical usage guide for setup instructions.
- Add an IaC scanner to your CI pipeline for pre-apply validation.
- Schedule infrastructure scans with Powerpipe or Prowler to verify deployed resources.
- Explore the supported frameworks to find the right compliance baseline.
For a broader comparison of building compliance yourself versus using compliance.tf modules, see Why Enterprises Choose Compliance.tf Over terraform-aws-modules.
Found this useful?
Share it with your team or post it on LinkedIn, X, or your favorite community.
Next Step
