June 2026
Compliant-by-Default AWS Storage
Terraform that provisions S3 storage with encryption, versioning, access blocking, and audit logging enforced at creation time - so the control is satisfied before an auditor ever asks.
Most control failures I see as an auditor are not decisions. Nobody chose to leave a bucket unencrypted - it was simply never configured, and the gap sat there until someone sampled it months later. The fix is not more testing. It is making the non-compliant configuration impossible to provision in the first place.
This module builds a primary bucket and a dedicated log bucket where every control is part of the resource definition rather than a follow-up task.
Controls implemented
| Control | Requirement | Implementation |
|---|---|---|
| SC-28 | Encryption at rest | aws_s3_bucket_server_side_encryption_configuration on both buckets |
| AC-3 | Access enforcement | aws_s3_bucket_public_access_block with all four flags set to true |
| CM-6 | Configuration settings | aws_s3_bucket_versioning plus mandatory tags applied through the provider’s default_tags |
| AU-3 | Audit record content | aws_s3_bucket_logging writing to a separate log bucket, with ownership controls and a log-delivery-write ACL |
Tagging is enforced at the provider level rather than per resource. That detail
matters: a default_tags block means a future engineer cannot add a bucket to
this module and forget the tags. The control holds without anyone remembering it.
Evidence as a build artifact
The interesting output is not the infrastructure - it is the proof.
terraform plan -out=tfplan
terraform show -json tfplan > evidence/plan.json
That JSON plan is a complete, machine-readable description of what the infrastructure will be, produced before anything is deployed. It contains the encryption rule, the four-flag public access block, the required tags, and the logging configuration.
For an auditor, this replaces a screenshot with something far better: a
structured artifact that can be tested automatically and regenerated on demand.
A companion verify.sh runs the same control checks against the live account
after apply, so the pre-deployment claim and the post-deployment reality can be
compared directly.
That plan file is exactly what the policy-as-code project consumes to enforce these same controls automatically on every change.