Terraform Tutorial — S3 Backend Setup
The S3 backend is the most popular choice for AWS teams. It stores state in an S3 bucket with optional encryption and versioning.
Step 1: Create the S3 Bucket
Create the bucket manually or with a separate Terraform config (bootstrap):
$ aws s3api create-bucket \
--bucket my-company-terraform-state \
--region us-east-1
Enable versioning:
$ aws s3api put-bucket-versioning \
--bucket my-company-terraform-state \
--versioning-configuration Status=Enabled
Enable encryption:
$ aws s3api put-bucket-encryption \
--bucket my-company-terraform-state \
--server-side-encryption-configuration '{
"Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"}}]
}'
Step 2: Configure the Backend
# backend.tf
terraform {
backend "s3" {
bucket = "my-company-terraform-state"
key = "projects/web-app/terraform.tfstate"
region = "us-east-1"
encrypt = true
}
}
Step 3: Initialize
$ terraform init
Initializing the backend...
Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.
Key Organization
Organize state keys by project and environment:
my-company-terraform-state/
├── projects/
│ ├── web-app/
│ │ └── terraform.tfstate
│ ├── api-service/
│ │ └── terraform.tfstate
│ └── shared-infra/
│ └── terraform.tfstate
└── environments/
├── dev/terraform.tfstate
├── staging/terraform.tfstate
└── prod/terraform.tfstate
Best Practices
| Practice | Why |
|---|---|
| Enable versioning | Recover from state corruption |
| Enable encryption | Protect sensitive data |
| Block public access | State contains secrets |
| Use a dedicated bucket | Separate from application data |
| Use IAM policies | Restrict who can read/write state |
What’s Next?
Add DynamoDB locking to prevent concurrent modifications.