Managing Terraform state in AWS S3 bucket. Create S3 bucket for storing the Terraform state and DynamoDB for keep the Terraform lock.
Resources
- AWS KMS key
- S3 bucket
- S3 bucket server side encryption
- S3 bucket acl and block public access
- S3 bucket versioning
- DynamoDB table
Create S3 bucket and DynamoDB table
terraform.tfvars
bucket_name = "terraform-backend-state"
main.tf
variable "bucket_name" {
type = string
description = "Bucket name to hold terraform state"
}
resource "aws_kms_key" "tf" {
description = "KMS Key to encrypt Terraform state and lock"
deletion_window_in_days = 7
}
resource "aws_s3_bucket" "bucket" {
bucket = var.bucket_name
tags = {
Name = var.bucket_name
}
}
resource "aws_s3_bucket_server_side_encryption_configuration" "encrypt" {
bucket = aws_s3_bucket.bucket.id
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = aws_kms_key.tf.id
sse_algorithm = "aws:kms"
}
}
}
resource "aws_s3_bucket_acl" "acl" {
bucket = aws_s3_bucket.bucket.id
acl = "private"
}
resource "aws_s3_bucket_public_access_block" "block_public" {
bucket = aws_s3_bucket.bucket.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
resource "aws_s3_bucket_versioning" "enable" {
bucket = aws_s3_bucket.bucket.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_dynamodb_table" "tf_state" {
name = "TerraformState"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
server_side_encryption {
enabled = true
kms_key_arn = aws_kms_key.tf.arn
}
tags = {
Name = "TerraformState"
}
}
Configure the backend in Terraform
state.tf
terraform {
backend "s3" {
bucket = "terraform-backend-state"
key = "development/us-east-1/my-website/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "TerraformState"
}
}