How to Lock Terraform State with S3 bucket in DynamoDB.

Christopher Quiles
5 min readOct 27, 2020

This lab will show you how to lock your Terraform state file in DynamoDB.

What is state and why is it important in Terraform?

“Terraform must store state about your managed infrastructure and configuration. This state is used by Terraform to map real world resources to your configuration, keep track of metadata, and to improve performance for large infrastructures. This state file is extremely important; it maps various resource metadata to actual resource IDs so that Terraform knows what it is managing. This file must be saved and distributed to anyone who might run Terraform.”

Remote State:

“By default, Terraform stores state locally in a file named terraform.tfstate. When working with Terraform in a team, use of a local file makes Terraform usage complicated because each user must make sure they always have the latest state data before running Terraform and make sure that nobody else runs Terraform at the same time.”

“With remote state, Terraform writes the state data to a remote data store, which can then be shared between all members of a team.”

State Lock:

“If supported by your backend, Terraform will lock your state for all operations that could write state. This prevents others from acquiring the lock and potentially corrupting your state.”

“State locking happens automatically on all operations that could write state. You won’t see any message that it is happening. If state locking fails, Terraform will not continue. You can disable state locking for most commands with the -lock flag but it is not recommended.”

NOTE: This lab assumes you already have downloaded Terraform and have an AWS account. If not here are a couple links to do so.

Terraform:
https://www.terraform.io/downloads.html

AWS:
https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/

Step 1:

Let’s create a new working directory labeled LOCKDOWN.

Mkdir creates a new woking directory in terraform.

Step 2:

We’re going to create a file labeled S3.tf.

Touch command creates new files in your working directory.

Step 3: Creating our S3 in Terraform.

Create a new file in your working directory labeled S3.tf

Copy and Paste this Terraform configuration into your source editor. However, you will need to choose a different name for your bucket!

provider "aws" {
shared_credentials_file = "~/.aws/credentials"
region = "us-east-1"
}

resource "aws_s3_bucket" "tf_course" {

bucket = "hella-buckets"
acl = "private"
}
Verify your bucket has been create in your S3 AWS console.

Step 4: Setting up our S3 Backend.

Create a new file in your working directory labeled Backend.tf

Copy and paste this configuration in your source code editor in your backend.tf file.

terraform {
backend "s3" {
encrypt = true bucket = "hella-buckets"
dynamodb_table = "terraform-state-lock-dynamo"
key = "terraform.tfstate"
region = "us-east-1"
}
}

Step 5: Creating our DynamoDB Table.

Create a new file in your working directory labeled dynamo.tf

Copy and paste this configuration in your source code editor in your dynamo.tf file.

resource "aws_dynamodb_table" "dynamodb-terraform-state-lock" {
name = "terraform-state-lock-dynamo"
hash_key = "LockID"
read_capacity = 20
write_capacity = 20

attribute {
name = "LockID"
type = "S"
}
}

What is DynamoDB?

Step 6: Let’s put it all together now.

Go ahead and run TERRAFORM INIT to initialize our backend. Then we are going to run a TERRAFORM APPLY and see what happens.

Step 7: Problem Solving State Lock Error.

After, you run Terraform Apply an error message might appear like the one below. Here’s what it means and how to get around it.

“If supported by your backend, Terraform will lock your state for all operations that could write state. This prevents others from acquiring the lock and potentially corrupting your state.

State locking happens automatically on all operations that could write state. You won’t see any message that it is happening. If state locking fails, Terraform will not continue.”

Use the following command to move forward with your apply.

terraform apply -lock=false

Step 8: Verifying and Testing our state lock with DynamoDB.

If you inspect .terraform/terraform.tfstate, you will see that it contains the location of the state file now instead of the actual state file.

Check your Dynamo DB table.

Also, notice under Items in DynamoDB we got the .tfstate file on Dynamodb with a Lock string. This will lock the .tfstate file to restrict multiple users’ access at a time for the same service location.

The final test is trying to destroy our terraform files. If we have a state lock terraform destroy will not be able to deploy with out access to the state lock. I mean it’s kind of the whole point of the project right?

terraform destroy
You should receive this message when trying to destroy.

--

--