The Problem

One of the many challenges that teams face when starting to work on a new serverless project in the cloud is how to work efficiently as a team. In traditional programming, you have your own workstation where you can test out your changes. You can use tools like Docker, pipenv, or virtual machines to create multiple isolated environments on the same machine. If you’re partnering with other coworkers, you can share your git branches to collaborate together.

With cloud services, it’s much more difficult to do that collaboration, especially if everyone is working on the same code base. Collaboration becomes even more difficult when you throw Terraform into the mix. All of a sudden, your infrastructure changes can break that shiny new feature that Bob is working on which also changes the infrastructure.

You may find yourself seeing too many messages from terraform planstating Plan: 9 to add, 6 to remove, 2 to change when all you did was change a few resources. You either yell at Bob to commit his changes, or you destroy his work (seriously, Bob is annoying).

The Solution

You can create separate accounts for everyone. Not always feasible depending on enterprise structure. You can get creative with how you work and collaborate, but that relies on people to follow a process. We all know people are fallible and forgetful — and we really don’t like processes.

What I have found most effective is to use terraform workspaces. By using terraform’s variables and locals to our advantage, you can effectively install n copies of your infrastructure to the same environment.

For instance, take the following infrastructure:

A CloudWatch Event kicks off a Lambda every 5 minutes and places it into a S3 bucket. Bob needs to modify the infrastructure to also download dog pictures. Bob runs the command terraform workspace new bob and switches himself over to the bob workspace. Bob modifies the names of all the resources and changes the Lambda code to go fetch dog pictures too. Now Bob can deploy the dog test infrastructure alongside the existing infrastructure, leaving it fully intact.

Once Bob merges his changes into master, he runs terraform destroy on his infrastructure followed by terraform workspace select default && terraform apply to apply his changes to the main test infrastructure.

It’s easy to envision that this works with 10 team members and 100 Terraform resources. That’s because it really does work that simply.

Implementation

In your main module, add the following:

locals {
  qualifier = terraform.workspace == "default" ? "" : "-${terraform.workspace"
}

This defines a local variable named qualifier that will be empty in the default workspace and -<workspace name> (e.g. -bob) in any other workspace. I’m assuming here that you have separate accounts for test/production. If you don’t, just add more logic to differentiate your environments in this block.

In each module, be sure to pass the qualifier:

module "automation" {
  source = "./automation/"
  qualifier = locals.qualifier
}

In the module, “accept” the variable by defining it:

variable "qualifier" {}

Finally, in all of your resources, add the following to the field tied to the resource name:

resource "aws_lambda_function" "download-kitty-picture" {
  name = "download-kitty-picture${qualifier}"
  ...
}

In your project’s initialization step, you’ll want to add something like the following to ensure that the user automatically switches to their personal workspace. Have your project initialization run the command: terraform init && terraform workspace new `whoami`; terraform workspace select `whoami`

Note the semicolon is important. If the workspace named after your user is already present, it will return a non-zero code. The semicolon ensures that the select command always runs.

In Summary

I hope this article was helpful to you! It really is easy to use Terraform workspaces to manage a team with a complicated architecture all working on the same code at the same time.

Next time, I’ll write about how to nag your teammates, or automatically delete their personal copies, when they haven’t torn down their infrastructure. Stay tuned!

Feel free to connect with me on LinkedIn.