Terraform Remote States in S3

Allan Denot
DNX Labs
Published in
3 min readMay 10, 2019

A simple way to use S3 backend to store your states remotely

Photo by Lachlan Gowen on Unsplash

When a terraform stack is deployed, terraform creates a state file.

The state file keeps track of what resources have been deployed, all parameters, IDs, dependencies, failures and outputs defined in your stack.

In a not so distant past, this state file (JSON) would be committed to the repository containing your terraform stack code.

This created a few problems:

  • Concurrency: If 2 or more developers are working in the stack, they won’t see the other state until it’s pushed to the repository
  • Automated Deployment: A CI tool that deploys the stack automatically would need to commit the new state file to the repository
  • Easily corruptible: In case of a merge conflict or human error, the state file can be corrupted or gone. If this happens, the stack becomes unmaintainable, resources need to be manually/individually imported or cleaned and then re-created with terraform

How remote state works

Instead of having a local JSON file holding the state, the state file is uploaded to an S3 bucket.

It’s all done automatically by the terraform S3 backend, example:

After deploying, terraform will create a state file called ecs-platform in the bucket dnx-terraform-backend.

If you use workspaces, it will prefix with /env:/<workspace_name>/.

To learn more, check our article on Terraform Workspaces

You probably noticed the parameter dynamodb_table above. DynamoDB is used for locking and consistency checking, to prevent concurrent operations in a single workspace.

Creating the backend infrastructure (bucket, DynamoDB table and IAM roles)

We have a terraform module to facilitate the infrastructure creation:

Usage example:

The module creates the following resources:

  • S3 Bucket named <bucket_prefix>-terraform-backend
  • DynamoDB table named terraform-lock
  • IAM Role: terraform-backend

When deploying the module above, terraform will create a state file as it does for every stack. The state file for this stack has to be stored as a file in your repository as the bucket to store state files doesn’t exist yet. Classic “chicken and egg” problem 🐔🥚. All newer stacks can use the bucket created by this stack to store the state from now on.

Using multiple AWS accounts

If you deploy the S3 backend to a different AWS account from where your stacks are deployed, you can assume the terraform-backend role from the other account, as long as it’s allowed in the assume_policy parameter (it supports multiple roles separated by comma).

As an example, we have a network stack deployed to a different account than the S3 backend, the configuration on that stack would look like:

Note the new parameter role_arn and change <AWS_ACCOUNT_ID_OF_BACKEND> above to the AWS account ID where your S3 backend was deployed.

With the configuration above, when running terraform init/apply, it will:

  • Assume the role defined in role_arn
  • Reach the S3 bucket dnx-terraform-backend
  • Create the file network if it doesn’t exist, or download it and use as state file
  • Run apply: create/update the resources
  • Assume again the role in role_arn
  • Upload the updated state file back to the S3 bucket

The module also automatically enables bucket versioning and disallows files being deleted using the role, making almost impossible to lose a state file.

Conclusion

Hopefully, this article was helpful in some way.

Please leave your feedback below as well as anything you would like to see added.

We work at DNX Solutions and help to bring a better cloud and application experience for digital native startups in Australia.

Our current focus areas are: AWS, Well-Architected Solutions, Containers, ECS, Kubernetes, Continuous Integration/Continuous Delivery and Service Mesh.

We are constantly hiring cloud engineers for our Sydney office, focusing on cloud-native concepts.

Check our open source projects at https://github.com/DNXLabs and follow us on our Twitter or Linkedin

--

--

Allan Denot
DNX Labs

Cloud, container platforms and occasionally ML