CategoriesTerraformUncategorized

How to Use Amazon S3 as a Terraform Backend

When working with Terraform, managing your state file is critical. By default, Terraform stores this state file (terraform.tfstate) locally on your machine. While that’s fine for small projects or individual development, it’s not ideal for collaboration or scalable infrastructure. That’s where remote backends like Amazon S3 come in.

In this post, you’ll learn how to configure an S3 bucket as a remote backend for your Terraform project, optionally using DynamoDB for state locking and consistency.

Why Use an S3 Backend?

Using Amazon S3 as a backend offers several advantages:

  • ✅ Remote, centralized storage of state files
  • ✅ Enables collaboration across teams
  • ✅ Supports state locking (with DynamoDB)
  • ✅ Versioning support for rollback
  • ✅ Secure and durable storage

🧱 Prerequisites

Make sure you have:

  • An AWS account
  • IAM permissions to create S3 buckets and DynamoDB tables
  • AWS CLI configured (aws configure)
  • Terraform installed (terraform -v)

Step 1 – Bootsrap Initial Terraform Resources (S3 & DynamoDb)

Initialize a terraform project with default local backend (no remote backend) and create s3 bucket and dynamo db which are the two resources needed for terrafrom s3 backend.

resource "aws_s3_bucket" "terraform_state" {
  bucket = "devops-terraform-state-009"
  force_destroy = true
}

This creates a bucket that will be used to store terraform state files, allowing team collaboration and state management.

This bucket will be used to store your Terraform state files, allowing team collaboration and state management.

force_destroy is set to so that when the bucket is deleted via Terraform, it will delete all the objects in it first (otherwise you’d need to empty the bucket manually before deleting it).

resource "aws_s3_bucket_versioning" "bucket_versioning" {
  bucket = aws_s3_bucket.terraform_state.id
  versioning_configuration {
    status = "Enabled"
  }
}

Enables versioning on the bucket. Allowing terraform to keep a history of all changes to the Terraform state file, and recover previous versions if needed.

resource "aws_s3_bucket_server_side_encryption_configuration" "bucket_configuration" {
    bucket = aws_s3_bucket.terraform_state.id
    rule {
        apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
        }
    }
}

Configures encryption at rest for the bucket using AES-256.

Ensures any data (like state files) written to the bucket is automatically encrypted.

resource "aws_dynamodb_table" "terraform_locks" {
  name = "terraform_state_loccking"
  billing_mode = "PAY_PER_REQUEST"
  hash_key = "LockID"
 
  attribute {
     name = "LockID"
     type = "S"
  }
}

Creates a DynamoDB table for state locking and consistency.

LockID is the key used to track the lock.

billing_mode = "PAY_PER_REQUEST" means you only pay for what you use—no provisioning needed.

This is used to prevent concurrent Terraform runs from corrupting the state file (e.g., two devs running terraform apply at the same time).

Execute the following commands in sequence:

terraform apply – Apply the planned changes to the infrastructure.

terraform init – Initialize the Terraform configuration.

terraform plan – Preview the changes Terraform will make.

This will create the s3 bucket and the DynamoDB table.

Step 2 – Switch to remote backend

Once this is complete. Update terraform to use s3 remote backend as follows:

backend “s3” {
bucket = “devops-terraform-state-009”
region = “us-east-1”
dynamodb_table = “terraform_state_locking”
encrypt = true
key = “tf-infra/terraform.tfstate”
profile = “terraform-user”
}

bucket = "devops-terraform-state-009"

Specifies the name of the S3 bucket where your Terraform state file will be stored. The bucket must exist before running terraform init.

region = "us-east-1"

Defines the AWS region where the S3 bucket (and DynamoDB table) is located.

dynamodb_table = "terraform_state_locking"

Points to a DynamoDB table used for state locking and concurrency control. This prevents multiple people or processes from applying changes at the same time, which could corrupt the state.

encrypt = true

Enables server-side encryption for the state file stored in S3, helping secure sensitive information.

key = "tf-infra/terraform.tfstate"

This is the path within the S3 bucket where the state file will be saved. It acts like a file name and can be nested within folders (e.g., “tf-infra”).

profile = "terraform-user"

Specifies the AWS CLI profile to use for authentication. This refers to credentials configured in your ~/.aws/credentials file under the [terraform-user] section

CategoriesPhotography

A Happy Sunday

Date: Sun 23, June 2024

Sundays are beautiful without effort.

But those Sundays when the sun is warm and the he sky is painted with soft, drifting clouds on the most gentle blue canvas—that’s nature showing off.

And if such a day comes with a cone of ice cream melting in your tired hands, how could you ask for more?

It has to be the Happiest of Sundays

CategoriesPhotography

Lagos Hustle Express

Date: September 25th, 2021

Deep in the heart of Nigeria, tucked within the crevices of Africa, lies a city that never sleeps—Lagos.

A city where the young and restless come searching for purpose. A place you hate to love.

A city of the bold.

A city of the fearless.

A city where dreams fight to live until the very last breath.

A city where ambition rides on steel, and resilience clings to every carriage.