Using a common Terraform Variables file for multiple workspaces

Today I put together a solution to make it easier for us to define and use Terraform variables across multiple workspaces. Usually when we deploy a project, the majority of the Terraform variables don't change between multiple workspaces - For example, for different environments or accounts. A lot of the variables will be to enable a thing, and configure it in the way you want, and most of the time you'll want it deployed in the same way everywhere.

When running terraform apply, we know we can use it the -var-file flag to provide it a file with our variables defined. We can also use this flag multiple times. If a variable is defined multiple times within the same file, Terraform will throw an error - However if it is defined multiple times across different files, it will use the value that was set last.

So I decided to use 3 files. The first one would basically be an example tfvars file, with everything defined, but not enabled, so by default nothing will deploy, but all the variables have values - This will be stored in the git repo, and can be public. The second is what I called the 'global terraform variables', which I would use to set the variables so that the infrastructure deploys in the way that I want - This one would be stored remotely, as it might contain secrets, so that it can be shared between our team (I wrote a blog post about how that can be achieved here). Lastly would be a tfvars file specific to a workspace, and each workspace would have it's own tfvars file - again these will be stored remotely.

We can now run terraform like so:

terraform apply \
  -var-file=default.tfvars \
  -var-file=global.tfvars \
  -var-file="$WORKSPACE_NAME.tfvars"

The advantage of doing this, is that we now only need to maintain the global.tfvars and add a few specific variables into "$WORKSPACE_NAME.tfvars". So if a new feature is added to a project or module, we would add the required variables into default.tfvars (which is stored along with the project), which will prevent crashes or user prompts. We could just add defaults to the variable block, but it can become a chore to read through large variable block files to find what a default is.

When it comes to creating a new workspace, we would just copy and rename the global tfvars file, and remove the options we don't want to change 👍

Of course we have automated all of this, within our wrapper that we use around Terraform to help us deploy to multiple AWS accounts - We hope to open source this soon 😉