Goodbye DynamoDB — Terraform S3 Backend Now Supports Native Locking

Rafael Medeiros

--

Terraform’s S3 backend now includes S3 native state locking as an opt-in experimental feature. This new locking mechanism can work independently or alongside a DynamoDB lock. When both are enabled, Terraform must successfully acquire a lock from both sources before proceeding with any operations.

Why S3 Native State Locking?

Terraform relied on DynamoDB-based locking to prevent state file conflicts when multiple users or automation processes accessed it. While effective, this approach required maintaining an extra AWS resource (a DynamoDB table) — which added cost and complexity.

With S3 native state locking, Terraform introduces a built-in locking mechanism that works without DynamoDB. You can still use it alongside DynamoDB for redundancy, but once fully transitioned, you’ll no longer need to manage a separate lock table.

How to Enable S3 Locking

First of all, make sure that your terraform version is 1.9.0 or greater. To enable S3 native state locking, simply set use_lockfile to true in your backend configuration:

Before: Using DynamoDB for Locking

terraform {  
backend "s3" {
bucket = "your-terraform-state-bucket"
key = "path/to/your/statefile.tfstate"
region = "us-east-1"
dynamodb_table = "your-dynamodb-lock-table" # Current state lock
encrypt = true
}
}

After: Switching to S3 Native Locking

terraform {  
backend "s3" {
bucket = "your-terraform-state-bucket"
key = "path/to/your/statefile.tfstate"
region = "us-east-1"
encrypt = true
use_lockfile = true #S3 native locking
}
}

How It Works

With S3 locking enabled, Terraform creates a lock file in the same location as the state file. This lock file shares the same name as the state file but has a .tflock extension. Depending on your setup, you may need to update S3 bucket policies and IAM permissions to accommodate the new lock file:

Here is the code if you want to give it a try:

terraform {  
backend "s3" {
bucket = "state-bucket-2025"
key = "dev/terraform.tfstate"
region = "us-east-1"
encrypt = true
use_lockfile = true #S3 native locking
}
}


variable "region" {
type = string
default = "eastus"
}

resource "aws_instance" "example_instance" {

ami = "ami-12345678"
instance_type = "t3.micro"


tags = {
Name = "ExampleInstance-${var.region}"
}
}

Future Updates

In an upcoming minor version of Terraform, the use_lockfile attribute will graduate from experimental to fully supported. At that point, attributes related to DynamoDB-based locking will be deprecated.

Follow me on Linkedin!

--

--

Responses (1)