Happy new year. This is the year that I will finally be able to move on from a vague understanding of DevOps to feeling that I have a fairly good understanding. To go with my new found experience and confidence I have decided to at least once a month put up an article discussing something I have been working on during that month. The idea is to help me remember to share some of my experiences and of course to help other people who might have the same problems that I have experienced.

To start with I thought I would talk a little bit about terraform, starting with some basic commands that I have found to be useful, and eventually giving a working example of making a terraform provider.

Terraform Workspace

A Terraform workspace is a special separation of the terraform configuration to allow you to target different machines normally in different environments. This essentially allows you to have the typical dev/qa/production type of situation for your terraform configuration.

In order to use a workspace you will need to enable it by running the following command

terraform workspace new dev 

and then to switch workspaces

terraform workspace select dev

And there you have it, you can now target different workspaces in the same project without causing the environments to interfere with each other.

So? How does this help?

So far, workspaces don’t seem to do anything useful. How does this really help with anything? Well, lets work through a simple example to show how you could use this make your life easier.

The complete separation

The first approach is literally separate your environments into different directories, such as…

+
+- Dev
   +- .terraform
   |- terraform.tfstate
   |- terraform.tfstate.backup
   |- main.tf
+- QA
   +- .terraform
   |- terraform.tfstate
   |- terraform.tfstate.backup   
   |- main.tf
+- Prod
   +- .terraform
   |- terraform.tfstate
   |- terraform.tfstate.backup   
   |- main.tf

This approach does not need workspaces at all and you are completely isolated from each environment. This means that you absolutely cannot perform a change on Dev which suddenly happens on Prod, but you will also need to duplicate everything common between each environment. This can be especially painful if you are adding addition providers to the .terraform directory. In simple scenarios the above approach works fine, once you start getting into more complex environments it quickly becomes painful to try and split the environments up like this.

Use workspaces instead

Lets use workspaces instead, now the following is just my suggestion about how to layout this type of configuration and should be taken as a example suggestion. So instead of the above directory structure you can do as follows

+
+- .terraform
+- dev
   |- main.tf
+- QA
   |- main.tf
+- prod
   |- main.tf
+- terraform.tfstate.d

And each sub directory will have a workspace associated with it. Unlike the above example only one .terraform directory exists and the terraform.tfstate is folded into the terraform.tfstate.d location instead. To work with this setup you will need to run commands like this from the base directory

terraform worksapce select dev
terraform init ./dev
terraform plan ./dev
terraform apply ./dev

A second benefit to this approach is that is you somehow do accidentally target the wrong environment / workspace you should see the problem in the plan stage.

You should try and mess around with workspaces, they will help ensure that your environments can be kept separate without having to introduce messy workarounds, and it also allows you to keep common configuration easily accessible.