Until this week, the first line on compliance.tf read "Terraform Modules That Prevent Infrastructure Audit Findings", and the line under it promised a one-line drop-in from terraform-aws-modules. Both lines described the first version of the product well, and they said nothing about the questions people asked me after trying it.
The new first line is "Know which controls your Terraform enforces. Prove it." This post explains what pushed me to change it, who it is written for, and what shipped around it.
People asked where the exceptions live
Swapping a module source is easy to explain and easy to try. The conversations that followed were about something else: what happens when a control does not fit one resource, who decided that, and where it is written down.
A control will not fit every resource. Object Lock retention on a development bucket is the example in our docs: it is a reasonable control for production and rarely worth the effort in a dev account. A scanner suppression comment hides the finding and records nothing an auditor can follow. So the exception had to become code too.
On a framework endpoint, the exception is a query parameter on the module source:
module "s3_bucket" {
source = "https://soc2.compliance.tf/terraform-aws-modules/s3-bucket/aws?version=5.0.0&disable=s3_bucket_object_lock_enabled"
bucket = "my-app-data-dev"
}
It goes through the same pull request as any other change, it stays in Git history and in .terraform/modules/modules.json, and ctfkit reports the disabled control as a finding in CI. A query parameter records no reason, so the reason still goes in the pull request.
For an organization, exceptions are waivers: one control or rule in one environment, proposed and then approved, applied to production when the next approved config is promoted there, and recorded in the audit trail. The expiry decides whether a waiver can be included in that promotion; it is not a timer that removes a live exception. Requiring a different person to approve than the one who proposed is off by default; we turn it on for an organization on request.
Once the exception lives in code, the question people ask is which controls their Terraform enforces and where that is recorded, and a hardened module answers only the first half.
Hand-written resources need controls too
The second trigger was my own experiment with the compliance.tf provider for AWS. Some existing Terraform declares aws_* resources directly, with no module around them, and a module source line does nothing for those.
The provider runs the official hashicorp/aws provider unmodified and checks those resources before Terraform calls AWS. You adopt it by changing the provider source and running one terraform state replace-provider, so nothing is recreated. Its built-in CIS baseline has 18 controls on 11 resource types, free, without an account or a token. The default soft_fail mode warns; in hard_fail mode it fails the plan and names the control and the fix, and with COMPLIANCETF_DIAGNOSTICS=full also its framework references. It checks resources in the root module, and in a child module only when that module itself requires the compliance.tf provider. A child module that requires hashicorp/aws, which includes every terraform-aws-modules module, or that declares no provider requirement at all, is not checked. For terraform-aws-modules, point the module source at a compliance.tf framework endpoint instead, and the module arrives with that framework's controls applied.
With the provider in the picture, "drop-in modules" covered only part of what compliance.tf does.
Who the new wording is for
I wrote it for the platform team that owns the Terraform module standards for an AWS estate with many accounts, with an external audit it cannot afford to fail: SOC 2, PCI DSS, HIPAA or ISO 27001. That team already runs scanners or a policy engine. What it cannot say quickly is which setting inside a module satisfies which clause, and it rebuilds the evidence by hand every audit cycle.
A smaller team with a first audit date starts the same way as before: one source line, the free CIS tier or a 30-day trial with every framework, and the migration kit to decide which module to switch first.
What compliance.tf says now
The full sentence is: Compliance.tf makes a Terraform estate provable: the controls are built into the modules, held before apply, and mapped to the clauses your auditor asks about.
Controls are applied or checked in three places, all before apply. At terraform init, the module arrives from a framework or org endpoint with the controls applied. In CI, ctfkit checks your configuration or plan and names the compliance.tf module that closes each gap, from the command line, its GitHub Action or Spacelift hooks. Before the AWS API call, the provider checks hand-written resources. An org endpoint adds your baseline rules, such as allowed regions and deletion protection, to every module it serves.
The proof is the record compliance.tf keeps. Every control has a page with the clauses it maps to, and every framework page separates the mapped controls compliance.tf modules enforce from those another system has to cover. An organization adds config snapshots, promotion history and the audit log, and ctfkit report writes an evidence receipt from the module cache after init. The audit evidence guide shows how teams put it together.
The site also lists what compliance.tf does not prove: the deployed estate (your CSPM proves that), the runtime state of a resource, or that a given auditor accepts a mapping. It also cannot prove that the module it served is the one a team applied. That needs a plan check, which is on the roadmap.
What shipped with it
The website and the docs have a new design and the new wording, including the blog diagrams.
ctfkit, the open-source CI checker, now installs with brew install compliancetf/tap/ctfkit, has a Windows arm64 build, and its GitHub Action picks up the latest ctfkit by default. The compliance.tf provider for AWS keeps its version numbers in step with hashicorp/aws, so you pin the same version number. The docs now have Azure and Google Cloud control and framework reference pages; they are reference only, and Azure and Google Cloud modules are planned for Q1 2027.
Separately from compliance.tf, I released modules.tf, open-source agent skills for Claude Code and Codex that review, change and create Terraform modules by the rules terraform-aws-modules follows. It will help me review, fix and onboard new modules in terraform-aws-modules faster; the release post has the details.
Each of these gets its own post and demo over the next weeks. If the new wording does not match what you see when you try compliance.tf, or a page still says the old thing, I want to hear about it, good and bad.
