Terraform Standard Backends: S3 with versioning and state locking with DynamoDB
Tags: aws, cloud, terraform, devops
Published: 2022-06-28 02:11:26

We learned a little bit about Terraform's state and backend in the previous article. Now it is time to explore Terraform's Standard Backend in more detail.

Standard backends allow us to store the state remotely while modifying it locally through CLI. In essence it means that state is stored remotely while all Terraform operations are performed locally. We have seen an example of such backend in the previous article where we configured an AWS S3 bucket to store the state. We were still able to add resources, plan, and apply changes locally on our machine.

Here is the [link](https://www.terraform.io/language/settings/backends/s3) to the Terraform documentation regarding S3 backend. 

We can see that Terraform several backends. The following picture shows the list of the currently available backends. Official docs also have the settings you'd need to configure to make it work for each backend.

![Supported Terraform Backends](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r6s7ecjxs5dkgvp97dml.png)
 

One of the attractive features of cloud storage like S3 is that they come with file versioning. This means that state is versioned with minimal effort. Since this feature is outside of Terraform you need to find out how to enable versioning on your bucket.

Another benefit of cloud storage is that you can enable encryption of the state file. Enabling `Server-side encryption` for your bucket will add an extra layer of security to the Terraform state file. 

## State locking on AWS S3

Locking is not supported out of the box for S3 backend, we need to enable it using AWS DynamoDB table.

To enable this feature you will to do the following:
 - Create an S3 bucket. Enable `Versioning` and `Default Encryption`
![Creating S3 bucket with versioning and encryption to store Terraform State](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6creri6ztopx628fluup.png)
 
 - Create a DynamoDB table and select a name for Partition Key and table name (this is important). I chose table name "TF-locking" and partition key "lockID". Leave other settings as default and hit 'Create Table'.

![Creating a DynamoDB table for Terraform State Locking](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qbkwzry5t1dvxybbv8b2.png)
 

 - Modify the settings inside `terraform.tf` to let Terraform know about your new table. See the snippet below.
 -  We have successfully configured locking on S3!
```terraform
# terraform.tf

terraform {
  backend "s3" {
    bucket = "terraform-state-remote"
    key    = "dev/aws_infrastructure"
    region = "ca-central-1"

    dynamodb_table = "TF-locking"
    encrypt        = true

  }

  # other settings below ...
}
```

&nbsp;

Last thing we need to do is to run `init` command with reconfigure flag:
```bash 
$ terraform init --reconfigure
```

&nbsp;

To see locks you need to go the table you created and select 'View Items' and if there are any existing locks they would be displayed in the `lockID` column in the AWS console.

Thank you for reading! See you in the next article!