Skip to content
Welcome To Charanjit Cheema Blog

Welcome To Charanjit Cheema Blog

An Open Source and Cloud Blog

Menu
  • Home
  • About Me!
  • Way to my Technical Blog
  • Contact me
  • Privacy Policy
Menu

No More DynamoDB! Use Native S3 locking for Terraform State

Posted on February 7, 2025February 7, 2025 by Charanjit Singh

If you’ve been managing your Terraform state in AWS S3, you’ve probably been using DynamoDB to enable state locking. Well, here’s some great news: Terraform 1.10 lets you ditch DynamoDB and handle state locking directly in S3! No extra tables, no extra costs, and no more unnecessary complexity.

So, how does it work? Let me break it down step by step.

 

What Changed in Terraform 1.10?

Previously, when using an S3 backend for Terraform state, you needed DynamoDB to prevent multiple users or processes from making simultaneous changes. This worked, but setting up and maintaining a DynamoDB table just for state locking felt like overkill.

With Terraform 1.10, HashiCorp introduced native S3 locking. By simply adding a new parameter “use_lockfile = true”, Terraform will automatically create a lock file in your S3 bucket whenever a state-changing operation is in progress. Once the process is done, the lock is released. Isn’t it simple, right?

 

Creating an S3 backend for storing the Terraform state file

Note: You can create an S3 backend and enable versioning through the AWS Console, but I’m doing it using the AWS CLI here.

  1. Create an S3 Bucket If you haven’t already created an S3 bucket for storing your Terraform state:

aws s3api create-bucket –bucket your-bucket-name –region your-region –create-bucket-configuration LocationConstraint=your-region

  1. Enable versioning to keep track of state file changes:

aws s3api put-bucket-versioning –bucket your-bucket-name –versioning-configuration Status=Enabled

 

 

Setting Up S3 State Locking Without DynamoDB

Alright, let’s get this up and running. Follow these steps to configure your Terraform backend to use S3 locking:

  1. Ensure You’re Using Terraform 1.10 or Later First things first, make sure your Terraform version is up to date. Run:

terraform –version

If you’re not on 1.10 or later, upgrade using:

terraform init -upgrade

  1. Modify Your S3 Backend Configuration Now, open your Terraform configuration file (usually backend.tf or inside main.tf) and update the backend settings like this:

terraform {

backend “s3” {

bucket       = “your-bucket-name”

key          = “path/to/your/statefile”

region       = “your-region”

use_lockfile = true  # This enables native S3 state locking

}

}

 

My example Terraform code with backend settings:

 

terraform {
    backend “s3” {
        bucket         = “cj-tf-state” # This is the name of the S3 bucket which I created
        key            = “RDS_SG/terraform.tfstate” # This is the name of the state file in the bucket. You can name it whatever you want.
        region         = “ap-south-1” # This is the region where the bucket is located
        use_lockfile   = true  # This enables native S3 state locking
    }
}
resource “aws_security_group” “existing_sg” {
  name        = “RDSSecurityGroup”
  description = “This security group was created manually but now we are managing it with Terraform.”
  vpc_id      = var.vpcid # The VPC ID is parameterized for security reasons. In your code, either replace it here with your actual VPC ID or provide it in a *.tfvars file, as I have done.
  ingress {
    from_port   = 3306
    to_port     = 3306
    protocol    = “tcp”
    cidr_blocks = [var.cidr_block] # Referencing the parameterized CIDR block due to security reasons. Replace it with your actual CIDR block or provide it in a *.tfvars file.
  }
}

3. Initialize Terraform Again After making these changes, reinitialize your configuration to apply the backend changes:

terraform init

 

Note: If you want to migrate your local Terraform state file to an S3 backend like I did, you’ll need to run a few additional commands as shown below. However, be sure to back up your state file first.

  • Run the following command to initialize Terraform and migrate the local state file to S3:

terraform init -migrate-state

  • After successful migration, confirm the state file is stored in S3:

terraform state list

  • Additionally, you can check the S3 bucket to ensure the state file has been uploaded.

  • Remove Local State File (It is an Optional)

Once you’ve confirmed that the migration is successful, you can remove the local state file for security:

rm terraform.tfstate terraform.tfstate.backup

 

That’s it! Now, whenever Terraform runs, it will automatically create a lock file in your S3 bucket. If another process tries to make changes while a lock is active, Terraform will block it until the lock is released.

In the example below, I’m attempting to run the previously mentioned AWS RDS service Security Group provisioning Terraform code from two different Windows and Linux machines. However, Terraform has successfully detected the state file locking in S3, preventing any overwrites of the backend state file:

 Screenshot: terraform apply command executed in Windows machine

 

Screenshot: terraform apply command executed in Linux machine

Why Use Native S3 Locking?

  • No More DynamoDB – One less AWS service to configure, manage, and pay for.
  • Simpler Setup – Just one setting in your backend config and you’re done.
  • Still Secure – S3 provides strong consistency, ensuring your state remains protected.
  • Cost-Effective – Since you’re not using DynamoDB, you avoid additional costs.

 

Any Downsides?

Right now, this feature is still new, so it’s a good idea to test it in a lower environment before rolling it out to production. Also, if you have existing state files that rely on DynamoDB, you’ll need to plan your migration carefully.

 

Example Terraform code related to this topic

You can check my Below GitHub link in which you can see how I have written code as per real-world examples:
https://github.com/cjcheema/terraform_remote_state_locking_example

 

Wrap Up !

Terraform’s new native S3 locking is a game changer. It simplifies infrastructure management, reduces AWS costs, and keeps your state secure without extra overhead. If you’re still using DynamoDB for locking, it’s time to move on.

So, go ahead, update your Terraform configs, and enjoy a more streamlined workflow. If you like my article please comment and share it in your network. Happy automating!

Loading

  • Author
  • Recent Posts
Charanjit Singh
Follow him
Charanjit Singh
Charanjit is currently working as a Cloud Architect at Mphasis, with 18 years of experience in IT infrastructure projects, implementation, and support. While his main role is as a DevOps engineer, he holds a Cloud Architect position and has strong skills in cloud technologies and automation. His expertise includes Terraform, AWS, Azure DevOps, Azure Cloud, VMware, and Linux systems.

Charanjit is passionate about automating tasks and improving processes. He uses tools like Terraform and Azure DevOps to build and manage cloud infrastructure and streamline deployment. He also enjoys using Shell scripts and Ansible playbooks to make systems run more efficiently.

In his free time, Charanjit enjoys learning about new technologies and sharing his knowledge through his blog. When he’s not working, he likes listening to music, having a cup of coffee, and relaxing in nature.

You can connect with Charanjit on Twitter, Facebook, LinkedIn, or email him at charanjit.cheema@cjcheema.com.
Charanjit Singh
Follow him
Latest posts by Charanjit Singh (see all)
  • How to Deploy Docker Containers with NGINX on AWS EC2 Using Ansible and GitHub Actions - April 26, 2025
  • No More DynamoDB! Use Native S3 locking for Terraform State - February 7, 2025
  • How to Bring and Manage Manually Created AWS Resources Under Terraform Management - January 31, 2025

Like this:

Like Loading...

Related

Leave a ReplyCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Tags

AWS Cloud Computing Dockers Networking Open Networking OpenSource RHEL-CentOS SDN Server Hardware SLES tcpdump Ubuntu WSL

Follow me @

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 2 other subscribers

Recent Posts

  • How to Deploy Docker Containers with NGINX on AWS EC2 Using Ansible and GitHub Actions
  • No More DynamoDB! Use Native S3 locking for Terraform State
  • How to Bring and Manage Manually Created AWS Resources Under Terraform Management
  • Iterating Cloud Resource Provisioning Using Terraform Count and For_Each Meta-Arguments
  • Terraform and Ansible Collaboration for AWS Cloud Deployment

Recent Comments

  1. Charanjit Singh on Terraform and Ansible Collaboration for AWS Cloud Deployment
  2. christinatodd2020aeaa798563 on Terraform and Ansible Collaboration for AWS Cloud Deployment
  3. Charanjit Singh on How to Set password policy in CentOS or RHEL system
  4. SAURABH on How to recover or rebuild initramfs in CentOS 7 Linux
  5. Sangita on How to Set password policy in CentOS or RHEL system

Archives

  • April 2025
  • February 2025
  • January 2025
  • August 2024
  • July 2024
  • June 2024
  • January 2024
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • September 2022
  • August 2022
  • July 2020
  • May 2020
  • February 2020
  • November 2019
  • June 2019
  • May 2019
  • March 2019
  • February 2019
  • December 2018
  • November 2018
  • October 2018
  • September 2018
  • August 2018
  • June 2018
  • May 2018
  • April 2018

Categories

  • Automation
  • Cloud Computing
  • Coding
  • CyberSecurity
  • Networking
  • OpenSource
  • RHEL-CentOS
  • Server Hardware
  • SLES
  • Technical Blog
  • Ubuntu
  • WSL

Blog Stats

  • 18,353 hits
Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here: Cookie Policy
  • Home
  • About Me!
  • Way to my Technical Blog
  • Contact me
  • Privacy Policy
© 2025 Welcome To Charanjit Cheema Blog | Powered by Superbs Personal Blog theme
 

Loading Comments...
 

    %d