Blog

How to synchronize Terraform Cloud VCS triggered runs with your CI/CD pipeline

21 Apr, 2022
Xebia Background Header Wave

How do you synchronize Terraform Cloud VCS triggered runs with your CI/CD pipeline? In this blog I will present you
with a small utility which allows you to find all runs associated with a commit and wait for its completion.

Terraform Cloud runs can either be triggered via an explicit API call, or through a push to your git repository. The latter is known as VCS triggered run. VCS triggered runs
have two advantages: it allows you to trigger multiple workspace runs on a single commit and secondly, limit
access to the Terraform Cloud Workspace at the same time.

The downside is that the VCS triggered run starts in parallel with the CI/CD pipeline. So,
if you want to run a system test in the CI/CD pipeline, you will have to wait for the Terraform
run to be succesfully applied. Similarly, you want to abort the CI/CD pipeline when
the Terraform run errored.

For this particular purpose, we created the utilities tfe-run-wait and tfe-run-apply. The
utility tfe-run-wait will search for all workspaces that are affected by the commit and
wait until the run reaches a specified state. tfe-run-apply on the other hand, will apply
the run. In the next two sections I will show you how to use both these utilities.

Wait on Terraform Cloud VCS triggered run

To demonstrate the utility, we created the tfe-run-wait-demo
repository, which will always plan and apply. So after you commit and push a change, type:

tfe-run-wait --organization binx-io 
             --clone-url https://github.com/binxio/tfe-run-wait-demo.git 
             --branch main 
             --commit-sha $(git show --format=%H --no-patch)

This will search for all the runs associated with the commit and produce the following output:

INFO: waiting for run in binx-io:tfe-run-wait-demo for commit 304826b in repository https://github.com/binxio/tfe-run-wait-demo.git
INFO: found run https://app.terraform.io/app/binx-io/workspaces/tfe-run-wait-demo/runs/run-LqoFvBGZS6WVMLAr for commit 304826b
INFO: run-LqoFvBGZS6WVMLAr in workspace tfe-run-wait-demo in status planning, waited 1s
INFO: run-LqoFvBGZS6WVMLAr in workspace tfe-run-wait-demo has reached state cost_estimated
https://app.terraform.io/app/binx-io/workspaces/tfe-run-wait-demo/runs/run-LqoFvBGZS6WVMLAr
--------------------------------------------------------------------------------
Terraform v1.1.8
on linux_amd64
Configuring remote state backend...
Initializing Terraform configuration...
Terraform 1.1.8
local_file.timestamp: Plan to create
Plan: 1 to add, 0 to change, 0 to destroy.
--------------------------------------------------------------------------------

As you can see the plan is shown as well. If more workspaces were associated with this repository branch, each of the runs would be shown.

Apply a Terraform Cloud VCS triggered run

If you want to inspect the plan before you apply the change, you can use tfe-run-wait together
with tfe-run-apply with the confirm option. After a push, type:

tfe-run-wait --organization binx-io 
             --clone-url https://github.com/binxio/tfe-run-wait-demo.git 
             --branch main 
             --commit-sha $(git show --format=%H --no-patch) 
             --wait-for-status cost_estimated 

This will search for the runs associated with the commit and produce the following output:

INFO: found run https://app.terraform.io/app/binx-io/workspaces/tfe-run-wait-demo/runs/run-Tniodf33JHKMPrq6 for commit a7a94e8
INFO: apply run in binx-io:tfe-run-wait-demo for commit a7a94e8 in repository https://github.com/binxio/tfe-run-wait-demo.git
https://app.terraform.io/app/binx-io/workspaces/tfe-run-wait-demo/runs/run-Tniodf33JHKMPrq6
--------------------------------------------------------------------------------
Terraform v1.1.8
on linux_amd64
Configuring remote state backend...
Initializing Terraform configuration...
Terraform 1.1.8
local_file.timestamp: Plan to create
Plan: 1 to add, 0 to change, 0 to destroy.
--------------------------------------------------------------------------------

It shows the plan. If you are satisfied with the plan, type:

tfe-run-apply --organization binx-io 
--clone-url https://github.com/binxio/tfe-run-wait-demo.git 
--branch main 
--commit-sha $(git show --format=%H --no-patch) 
--comment 'it is all good' 
--confirm

This will result in the following output:

INFO: found run https://app.terraform.io/app/binx-io/workspaces/tfe-run-wait-demo/runs/run-LqoFvBGZS6WVMLAr for commit 304826b
INFO: apply run in binx-io:tfe-run-wait-demo for commit 304826b in repository https://github.com/binxio/tfe-run-wait-demo.git
https://app.terraform.io/app/binx-io/workspaces/tfe-run-wait-demo/runs/run-LqoFvBGZS6WVMLAr
--------------------------------------------------------------------------------
Terraform v1.1.8
on linux_amd64
Configuring remote state backend...
Initializing Terraform configuration...
Terraform 1.1.8
local_file.timestamp: Plan to create
Plan: 1 to add, 0 to change, 0 to destroy.
--------------------------------------------------------------------------------
want to apply this plan?

As you can see, it prompts for your input. If you confirm, the following output will appear:

INFO: apply run run-LqoFvBGZS6WVMLAr in workspace tfe-run-wait-demo from status cost_estimated
INFO: found run https://app.terraform.io/app/binx-io/workspaces/tfe-run-wait-demo/runs/run-LqoFvBGZS6WVMLAr for commit 304826b
INFO: run-LqoFvBGZS6WVMLAr in workspace tfe-run-wait-demo in status applying, waited 1s
INFO: run-LqoFvBGZS6WVMLAr in workspace tfe-run-wait-demo has reached state applied
--------------------------------------------------------------------------------
Terraform v1.1.8
on linux_amd64
Initializing plugins and modules...
Terraform 1.1.8
local_file.timestamp: Plan to create
local_file.timestamp: Creating...
local_file.timestamp: Creation complete after 0s [id=ba962809cc884a9cda2a28a6a0f39ba538100067]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs: 0
--------------------------------------------------------------------------------
INFO: apply of commit 304826bd000cf6755cf4b950d3f22d4be63e780c from repository https://github.com/binxio/tfe-run-wait-demo.git affected 1 workspaces, 0 failed

The utility will continue prompting to apply all affected workspaces. If you omit the --prompt it with automatically apply all the runs.

installation

You install the utility, by typing:

pip install tfe-run-wait

Alternatively you can use the Docker container image ghcr.io/binxio/tfe-run-wait:0.7.0 or the Github action binxio/tfe-run-wait-action.

For a short description of all command line options, checkout tfe-run-wait.

Conclusion

The tfe-run-wait and tfe-run-apply utilities allow you to synchronize CI/CD pipelines with Terraform Cloud VCS triggered runs.

Photo by Angela Loria on Unsplash

Mark van Holsteijn
Mark van Holsteijn is a senior software systems architect at Xebia Cloud-native solutions. He is passionate about removing waste in the software delivery process and keeping things clear and simple.
Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts