Protecting your Terraform State | Blog | Dines App

Protecting your Terraform State

Stephen Jefferson -

Lead Platform Engineer

This post was originally posted to

When applying a Terraform template, the state of the infrastructure being deployed is stored in a local terraform.tfstate file. If you're the sole developer on a project, having this stored in your project folder or a repo may work for you; in a team, you want to ensure that the latest version of your Terraform state is stored in a central place and source control isn't the best solution for this.

You don't want to get into a situation where multiple developers are working on the same cloud infrastructure stack and are stepping on each other's toes. You need a solution which prevents corruption of a stack, keeps revision history and removes sensitive files from your project structure (which could be on multiple desktops).

So where should I store it?

Saving Terraform State in S3

Terraform allows you to store this state in an S3 bucket by using a backend resource 🎉

1. Creating an S3 bucket

In AWS, you need to create an S3 bucket.

2. Integrating with your S3 Bucket

Now you have created your S3 bucket, you're ready to create a Backend resource, which allows Terraform to store and read the state from S3.

terraform { backend "s3" { bucket = "{your-bucket-name}" encrypt = true key = "path/to/state/state.tfstate" # Where you want to store state in S3 region = "{your-bucket-region}" } }

Prevent Concurrent Deployments

Now that your Terraform state is stored in an S3 bucket, how do we prevent multiple people applying a stack at the same time? 🤯

We will keep a file lock in a DynamoDB table 😁

1. Creating a DynamoDB table

In AWS, you need to create a DynamoDB table.

2. Integrating with your DynamoDB table

Now you have created your DynamoDB table, you're ready to integrate your backend with this to ensure your Terraform state is locked when applying changes.

terraform { backend "s3" { bucket = "{your-bucket-name}" dynamodb_table = "{your-dynamodb-table-name}" # This is the new key encrypt = true key = "path/to/state/state.tfstate" region = "{your-bucket-region}" } }

Voila, done! 💥

There is a lot of material out there on how to set this up but it is something I enjoyed doing, in a short amount of time, while wanting to start blogging, so here is my first on even though it's not the first of this type of article!

Permissions: You will need to ensure that the AWS profile you are using has the correct permissions to access the S3 bucket and perform the correct operations against the DynamoDB table. These can be found here: