Store Terraform state in S3¶
When you finish, every terraform apply for your AWS cluster reads and writes its state in a versioned, encrypted S3 bucket that blocks public access.
S3 locks state with use_lockfile, so you need no DynamoDB table.
Before you start¶
- AWS credentials that can create and configure the bucket
- Terraform 1.11 or later
1. Create a versioned bucket¶
aws s3 mb s3://my-terraform-state-bucket --region us-east-1
aws s3api put-bucket-versioning \
--bucket my-terraform-state-bucket \
--versioning-configuration Status=Enabled
The first command prints make_bucket: my-terraform-state-bucket, and the bucket keeps every prior revision of your state.
2. Point Terraform at the bucket¶
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket" # <-- Replace with your bucket name
key = "qumulo/aws/prod.tfstate" # <-- Replace with your path in the bucket
region = "us-east-1" # <-- Replace with your bucket region
use_lockfile = true
encrypt = true
}
}
Run terraform init -upgrade. If local state already exists, Terraform offers to migrate it into the bucket.
The output ends with Successfully configured the backend "s3"!
3. Lock down the bucket¶
Encrypt everything in the bucket with SSE-S3.
aws s3api put-bucket-encryption \
--bucket my-terraform-state-bucket \
--server-side-encryption-configuration '{"Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"}}]}'
Block every form of public access.
aws s3api put-public-access-block \
--bucket my-terraform-state-bucket \
--public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
Confirm that versioning is on.
The output includes "Status": "Enabled".
Next¶
Deploy your cluster with the basic AWS cluster example. When you need another backend option, see the Terraform s3 backend reference.