Terraform
Terraform should own all long-lived AWS resources: S3 buckets, CloudFront distributions, Lambda functions, IAM roles, Secrets Manager references, and optionally WAF associations. Keep modules small enough to review and environments isolated by workspace or directory—match whatever the Rendorix infra repository standardizes on.
Module layout
Section titled “Module layout”A typical split (names vary by repo):
| Module or layer | Owns |
|---|---|
| Network / DNS (optional) | Route 53 records, ACM certs in us-east-1 for CloudFront. |
| Storage | S3 bucket for originals, encryption, lifecycle, bucket policies. |
| Compute | Lambda for image transform, layers, env vars, concurrency settings. |
| Edge | CloudFront distribution, origins, behaviors, OAC, cache and query policies; CloudFront Function or Lambda@Edge attachments. |
| Secrets | IAM for reading signing keys; sometimes the secret resource if created by Terraform (avoid storing raw HMAC in .tfvars in VCS). |
Smaller teams sometimes use one root module first; split when plan output becomes hard to audit.
Required variables
Section titled “Required variables”Define explicitly (examples only):
- Environment name (
dev,staging,prod). - AWS region for regional resources (S3/Lambda); CloudFront is global but ACM for CloudFront must be in us-east-1 in standard setups.
- Domain / hosted zone id for DNS if Terraform manages records.
- Reference to signing secret (e.g. Secrets Manager ARN), not the secret value in plain text.
- Image Lambda zip or container uri if your pipeline builds artifacts outside Terraform.
Use validation blocks and descriptions on variables so misconfiguration fails early.
plan and apply workflow
Section titled “plan and apply workflow”- Format and validate:
terraform fmt,terraform validate. - Plan in CI for every merge to main and for production applies:
terraform plan -out=tfplanwith read-only credentials where possible for PR plans. - Apply with the saved plan:
terraform apply tfplanso what runs matches what was reviewed. - Review plans for destroy operations on stateful resources (buckets, distributions).
For drift: run terraform plan periodically; detect manual console changes and import or revert them.
State and locking
Section titled “State and locking”- Remote state in S3 with DynamoDB locking is a common default; encrypt the state bucket and restrict IAM to CI and break-glass roles.
- Separate state per environment to limit blast radius of a bad apply.
- Never commit
terraform.tfstateto git for real environments.
Document who may run apply in prod and how break-glass unlocks work if lock sticks.
CI integration
Section titled “CI integration”- PR pipeline:
fmtcheck,validate,plan(non-interactive), post plan as a comment or artifact. - Main / release pipeline: gated apply to staging first, then prod with manual approval if required.
- OIDC from GitHub Actions (or similar) to AWS without long-lived static keys on runners when possible.
Pin Terraform and provider versions in required_version and required_providers for reproducible plans.
Related reading
Section titled “Related reading”- AWS setup — accounts, quotas, alarms
- Deployment overview — checklists and verification
- Tradeoffs — what Terraform does not automate (abuse, product policy)