Blog / Terraform
Infrastructure as Code with Terraform: Best Practices for AWS
Infrastructure as Code turns "it works on the console" into a reviewed, repeatable, version-controlled system. Here are the Terraform practices that keep AWS infrastructure clean as a team grows.
1. Remote state with locking
Store state in an S3 bucket with a DynamoDB lock table. Never keep state on a laptop, remote state lets the whole team (and CI) work safely without clobbering each other.
terraform {
backend "s3" {
bucket = "mycompany-tfstate"
key = "prod/network.tfstate"
region = "us-east-1"
dynamodb_table = "tf-locks"
encrypt = true
}
}2. Build reusable modules
Wrap common patterns (a VPC, an ECS service, an RDS instance) into modules with clear inputs and outputs. You write it once, review it once, and reuse it everywhere, consistently.
3. Separate environments cleanly
Keep dev, staging and prod isolated, separate state and variables per environment. New environments then spin up identically in minutes, with no drift and no "works in staging" surprises.
4. Plan in CI, apply on approval
Run terraform plan automatically on every pull request so reviewers see exactly what will change. apply only after approval. Infrastructure changes become as reviewable as code.
5. Least privilege and no secrets in state
- Scope the Terraform role to only what it manages.
- Keep secrets in AWS Secrets Manager or SSM, referenced, not hard-coded.
- Enable state encryption and restrict who can read the state bucket.
Key takeaways
- Remote state in S3 + DynamoDB locking, never local.
- Reusable modules for consistency.
- Isolated per-environment state, no drift.
- Plan on every PR; apply on approval.
- Least-privilege roles and no secrets in state.
Want your infrastructure as clean code?
I set up Terraform properly, remote state, modules, CI plans and all. Book a free call and I'll review your setup and send a clear plan.
Get a free DevOps audit →