DEV Community

Joseph D. Marhee
Joseph D. Marhee

Posted on • Originally published at Medium on

Continuous Delivery for Terraform with


Continuous Delivery (or the combination Continuous Integration and CD) is one pattern for keeping your project well tested (as far as delivering to production in concerned — other testing on changes themselves not withstanding)- eminently deployable. For projects like infrastructure provisioning and state management tooling like Terraform repositories, that typically means, upon a change to the release branch, running these changes and ensuring the manifests can still cleanly apply.

I recently created this project to deploy a multi-architecture Kubernetes cluster on Packet:


and having selected’s cloud CD tooling, all I needed to do once I activated my project:

was push a manifest, .drone.yml , with my build steps, and referencing some configuration options I’d need for Terraform to run successfully.

Before I lay out my manifest, in the project, I needed to store secrets in order to expose them to Drone when they go to run Terraform, so things like provider credentials, and other variable values that you might normally put into terraform.tfvars when you run it locally:

With those values stored, in your manifest, you can reference these values and put them into environment variables (i.e. for a variable called count_x86, rather than declaring in tfvars , you could export a variable like TF_VAR_count_x86 ):

kind: pipeline

name: default


- name: Deploy

  image: alpine



          from_secret: TF_VAR_auth_token


          from_secret: TF_VAR_count_x86


          from_secret: TF_VAR_count_arm

and then to do things like install and run Terraform, validate, and then apply the changes to your repository’s Terraform manifests, you can provide commands in a list like the following:


  - apk --update add curl

  - curl --silent --output ""

  - unzip ; rm -f; chmod +x terraform

  - mkdir -p ${HOME}/bin ; export PATH=${PATH}:${HOME}/bin; mv terraform ${HOME}/bin/

  - terraform -v

  - terraform init

  - terraform validate

  - terraform apply -auto-approve

  - terraform destroy -auto-approve

and then, upon pushes to your target branch (in my case, master ), a new test run will begin:

with the output from your build steps, in our case a single stage called Deploy (you might repeat this, for example, to test different server types in different facilities — TF_VAR_facilityin our case- or just if a change requires multiple types of validation), written out to the console.

Further Reading

Top comments (0)