Introduction

Using workspaces when using Terraform gives you the ability to divide multiple different environments from each other.

As an example, you can divide stage environment from production by dividing them to two different workspaces. You can also divide job runs so the runs won’t override one another. You can fully control the division, easly.

How it works

Firstly, initialize your terraform directory by the command:

terraform init

Now you can start dividing your environments simply by using workspaces like this:

terraform workspace new productionexample

This will also automatically switch to the workspace you’ve just created above.

If you want to select an existing workspace you can just write:

terraform workspace select existingexample

After you’ve create a workspace and switched to it, your Terraform commands will be releated to that specific environment. You can run the same Terraform resources on different workspaces and these different workspaces won’t override each other.

Other useful workspace commands:

terraform workspace list //Will give you the list of the workspaces already exists 
terraform workspace delete exampleworkspace //Will delete the exampleworkspace

A pipeline implementation

In my terms of work, I’ve uploaded the terraform state file (state.tf) to an s3 bucket. In that way the state file is shared (obviously protected) and everybody I want to work with is aligned by this state file. The main problem I ran into is that if me and my colleagues were working on the exact same terraform environment we were sadly destroyed each other’s environments. But here comes the power of using workspaces. By dividing my work in a workspace, nobody could destroy my environment not on purpose. Now everybody can work on his own workspace without any interuption! This is just another example of usage you can do with Terraform workspaces. Not only dividing developement environment and production environment, you can use that option of division in many ways as you can see.

stage ("Setup Environment") { 
   steps { 
      dir ("terraform") { 
         sh "terraform init -input=false "
         sh "terraform workspace select ${ENV} || terraform workspace new ${ENV}" 
      } 
   } 
}

The ${ENV} is just an argument which gives me the full job name & path. It makes my workspace name almost unique (Not actually unique because I still want my builds to destroy each other, and not to create terraform workspace on every jenkins job run). So in this case I look for a workspace, and if it doesn’t exist I create it and switch to it.