Long Lived Branch Development with Terraform and Terraform Cloud
In this article we will take a look at a method of keeping long lived branches and how to interact with them in Terraform Cloud.
While other models and methods help, I found this approach to be fairly clean and straightforward within the repository. The main gist of things is we are going to use the ‘main’ branch as production and ‘dev’ branch as the dev environment. We will use some of Terraform cloud’s workspace and ‘cloud block’ feature to control what workspace is used during plans/applies.
Prerequisites
In order to follow along:
- sign up for a free Terraform Cloud account- https://app.terraform.io/
- you have terraform on your workstation. I am using latest (1.5.7).
- you have executed terraform login and have a valid tf cloud login linked with your shell.
- use your favorite version control system. I am using Azure DevOps
- I’m going to be using the VCS workflow so I have my workspaces linked up to monitor the repository, folders, and branches for changes.
Let’s Get Started
- The first thing we’ll do is create a new repository.
- in the main branch, create a folder named ‘app1’ and merge to main.
- create a second branch from main called ‘dev’ - Create 2 workspaces in Terraform Cloud.
- the first workspace name ‘app1-eastus2-dev’ create the second one as ‘app1-eastus2-prod’
- select the Version Control
- select the ADO/Github org and then the repository you created
- under advanced settings: for the ‘app1-eastus2-dev’ workspace the VCS branch should be ‘dev’, for ‘app1-eastus-prod’ you can leave this field blank
- under advanced settings: the terraform working directory should be ‘app1’
- click create - once the workspaces are created go into each of the workspaces and create some variables.
- in the dev workspace
— environment = dev
- in the prod workspace
— environment = prod
Now we should have a repository structure setup with 2 branches and 2 workspaces that have unique variables. We’ll run through a very simple TF code just to demonstrate the trunk based approach.
- clone the repository’s dev branch down. Create a new feature branch off dev.
- within the ‘app1’ folder, add a provders.tf file and drop the following code.
terraform {
cloud {
organization = "tfc org" #place your tf cloud organization here
}
}
terraform {
required_providers {
petstore = {
source = "terraform-in-action/petstore"
version = "~> 1.0"
}
}
}
3. create a main.tf file and drop the following code in.
variable "environment" {
}
resource "petstore_pet" "pet" {
name = "garfield-${var.environment}"
species = "cat"
age = 3}
4. since we are on the ‘dev’ branch, we want to use the ‘dev’ workspace. within your terminal session set the TF_WORKSPACE environment variable to your workspace name
export TF_WORKSPACE=app1-eastus2-dev
5. with the workspace environment variable set, we can now run terraform init and terraform plan. We will see that terraform CLI will use the environment variable to set the workspace and then will perform a plan. we have set the environment variable to ‘dev’ so we see the pet name = ‘garfield-dev’
6. ok now let’s PR that code and merge to dev. Terraform cloud will pick up those changes and prepare a plan within terraform cloud for you.
7. at this point some CI/CD pipelining would be utilized to perform tests and check approvals before applying the infrastructure changes to the dev environment. Another checkpoint within the CI/CD pipeline would approve the changes to be merged to main to go to production.
8. pretending everything was great, we will just run another terraform init/plan resetting our environment variable for TF_WORKSPACE to the prod workspace and execute a terraform init and terraform plan
export TF_WORKSPACE=app1-eastus2-prod
Hopefully this demonstrates one way trunk-based development can look with Terraform Cloud. Using the variables within Terraform cloud, you can manipulate a single code base on a per workspace (environment) bases and run the same exact code. This allows the codebase to stay very DRY and use the version control system to your advantage.