Terraform Dynamic Environment Variables through Workspaces and Local Values

We’ve fallen in love with Terraform and have moved all infrastructure over to using it on AWS. This is has been a huge win for our team and allows us to confidently deploy infrastructure changes across multiple accounts.

Our team uses 3 separate AWS accounts for each product we release — develop, staging and production. In doing this we often need different namespaces for services — like S3 buckets, API Gateway custom domains, CloudWatch log retention policies, etc.

To handle this we use Terraform’s awesome feature called workspaces which are:

Named workspaces allow conveniently switching between multiple instances of a single configuration within its singlebackend.

If you’re currently using Terraform, you’re already using the “default” workspace without realizing it. Try running terraform workspace list on an initialized Terraform project and it will return * default (the star indicates the workspace you currently are in).

Now let’s go ahead and create a new workspace called “develop” by typing terrarform workspace new develop. This will create a new workspace and automatically switch to that workspace.

Now let’s use this newly created workspace to start setting variables. Below is a simple example that has a local mapping of S3 buckets and domain names. Then below that on lines 15 & 16, we use those mappings and Terraform’s terraform.workspace object to map those to a single variable that we will use in later.

We can now use those locals we set above in the rest of our templates for each environment.

So now when you’re in the “develop” workspace, the S3 bucket, for example, will be “my-develop-bucket” and in staging “my-staging-bucket”.

You can use this for any resource or namings that are specific to an environment. It’s been a big win for us in having a single Terraform script that runs in all environments to ensure each environment is consistent.

comments powered by Disqus