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

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 is a senior software systems architect, and CTO of binx.io. He is passionate about removing waste in the software delivery process and keeping things clear and simple.
Share this article: Tweet this post / Post on LinkedIn