← All projects

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.

  • SC-28
  • CM-6
  • AC-3
  • AU-3
  • Terraform
  • AWS
  • S3
  • Infrastructure as Code

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.