DevOps Blog

One Terraform state S3 bucket for each of your AWS accounts

Written by Rémi Poux | 01-Apr-2020 22:00:00

AWS account architecture

The following figure shows what we want to establish.

The idea is to have an AWS root account, that gives the user access to 4 accounts:

  • Infra account: it contains the Terraform state bucket
  • Dev account: dev environment
  • Preprod account: preprod environment
  • Prod account: prod environment

We want to be able to perform a `terraform apply` from the AWS root account, that will access the Terraform state in the S3 bucket of the Infra account, in order to deploy resources on either one of dev, preprod or prod environments.

We assume in this article the user has set up the proper credentials and has currently access to the root account. We also assume that a role named “deploy” exists in each of the 4 non root accounts and that the user has the proper rights to assume this role in each account because Terraform will need this. If you didn’t already do it, then you’ll find here how to apply the same Terraform on multiple AWS accounts. Also find out here how AWS IAM roles work.

Setup Terraform provider and backend configurations

The main thing to understand here is that Terraform doesn’t use the AWS provider configuration in order to access the state bucket. It only uses the backend one.

So for this to work you need to configure the proper assume roles in the Terraform backend and provider configurations separately.

Backend configuration in `backend.tf`, add your Infra AWS account ID (the account that contains your state bucket) :

Provider configuration in `provider.tf`:

At this point, we can notice that it’s possible to use variables in the provider, whereas it’s unfortunately not possible to do so in the backend configuration. That’s not a problem for this example since the backend will be the same for all environments.

Setup workspaces configurations

Now you can setup a Terraform “.tfvars” file for each environment.

Dev configuration in `dev.tfvars`:

Preprod configuration in `preprod.tfvars`:

Prod configuration in `preprod.tfvars`:

And then create the associated Terraform workspaces:

Apply Terraform on one account

To be sure to deploy with Terraform your preprod environment on the preprod AWS account, for example, you can do this like this:

This is one way to make sure you use the configuration of the workspace you’re on while keeping the possibility to put configurations in different files: one for each workspace.

We saw in this article everything you will need to configure your Terraform deployment in order to use a Terraform state bucket that is stored in another AWS account. Terraform will this way be able to get its state from a bucket in one account, and then deploy in another account.