Verifying Compliance.tf Modules: From Guardrails to Audit Evidence

Learn how to validate compliance.tf modules with IaC scanners before deployment and infrastructure scanners after, what evidence auditors need, and how pre-apply and post-apply verification work together.

Anton Babenko

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

  1. Generate a Terraform plan

    bash
    terraform init
    terraform plan -out=plan.out
    terraform show -json plan.out > plan.json
    

    plan.json is the artifact you feed into IaC scanners.

  2. Run IaC scanners against the plan

    bash
    checkov -f plan.json
    trivy config plan.json
    

    With 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.

  3. 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

  1. Deploy infrastructure

    After terraform apply, resources exist in your AWS account.

  2. Run infrastructure scanners

    bash
    powerpipe control run aws_compliance.benchmark.cis_v300
    prowler aws --compliance cis_3.0_aws
    

    These tools verify the real state — catching drift and resources created outside Terraform.

  3. 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

  1. A developer writes Terraform using the S3 bucket module from compliance.tf.
  2. Checkov or Trivy scans the plan file and confirms logging is configured.
  3. Even if the developer passed logging = {}, the compliance.tf module enforces the requirement — the plan fails until logging.target_bucket is specified.

Post-apply

  1. After terraform apply, the S3 bucket exists in AWS.
  2. Powerpipe or Prowler queries the actual bucket and confirms logging is enabled.
  3. 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

Move from guidance to adoption

If you want the fastest path from scanner fatigue to preventive controls, start with a single module in a single environment. The migration surface is intentionally small.
Start the free trial