Bits and Bytes of Virtualization

Deploy Terraform Configuration via Azure Pipelines


I wanted to see if I could deploy infrastructure with Terraform via Azure Pipelines. To my surprise, there are Terraform extensions in the Azure Pipelines marketplace. These plugins allow me to get up to speed and achieve my goal quickly. This guide is not the only way to perform this integration but will allow you to get started. Therefore, I suggest modifying the steps and process to fit your needs.

Create a Project

First, you will need to create a new project within Azure DevOps. After logging into your DevOps organization, click Create Project to the right.

Create a new project within your DevOps organization

You will be presented with a quick project configuration box to complete. I named my project ‘Deploy Terraform Config’ as shown in the example.

Create a new project

Subsequently, your new project will show up and ask what services that you want to start with. This demo will use the Pipelines service. In addition, you may also use the Repos service if you didn’t already have your Terraform in an external repo.

Project created

Create a Build in Azure Pipelines

Next, I will create a new build pipeline. In the left menu, click Pipelines and then Builds. It will say there were no build pipelines found. Click ‘New Pipeline’ to proceed.

Create a build pipeline

The wizard will ask where my code is. For this example, I clicked ‘Use the visual designer’ link at the bottom.

Use the visual designer

Now I can select the repo where my Terraform code resides. If you are pulling the code from an external repo source, you will need to authorize the connection. In this example, I have already done that as shown by the green banner message. My repo can be found here. Click ‘Continue’ to proceed.

Select your code repo

The next step is to select a template. The examples available do not align with my pipeline goals, therefore, I will click ‘Empty job’ at the top.

Select Empty Job

After that, I am presented with a empty pipeline awaiting to add tasks.

Empty Build Pipeline ready for tasks

Before adding in tasks, click the down arrow next to ‘Save & queue’ and then select ‘Save’. This ensures the new pipeline is saved.

Saving a build pipeline

Add Secure Files

Next, I will add any secret files into my Pipeline Library. In the menu to the left, click ‘Library’. After that, click ‘Secure files’ at the top and then click the ‘+ Secure file’ button as shown.

Upload a secure file

It prompts me to upload my secure file. I will choose my ‘terraform.tfvars’ file that includes my secret Azure provider connection information. Later this secure file will be imported into a task in the build pipeline.

Upload terraform.tfvars

After the secure file has been uploaded, it will show up in the list of available secure files.

Add a secret file

Add Build Variables

Build variables will also be used throughout a few of the tasks during the build. Go back to ‘Builds’ in the menu and go back to the pipeline we began previously. Click ‘Edit’ in the top right to pick up where we left off. Then select ‘Variables’ and then ‘Pipeline Variables’.

Edit the build pipeline

In the center pane, I created the following variables:

  • access_key(secured) – The key used to access the storage account blob
  • container_name – The name of the container in my blob store.
  • pass(secured) – The password used for the guest OS in the deployed VM.
  • state_key – The name of the state file stored in the blob container.
  • storage_account_name(secured) – The name of the storage account where the Terraform state will be stored.
  • vmCount – How many VMs that should be deployed by Terraform.
Pipeline variables

Create Build Tasks

After my secure file is uploaded and variables created, I need to return to my build pipeline tasks. Then click the ‘+’ to the right of the default ‘Agent job 1’. The plus sign displays the list of available tasks that can be added. By default, the Terraform tasks I need to add are not available out of the box. Therefore, in the search box type ‘Terraform’. It searched the Marketplace and found a few available Terraform extensions. The extension I want has the name ‘Terraform Build & Release Tasks’ and is written by Charles Zipp. Click “Get it free’ to add it to the available tasks.

Get Terraform Build & Release Tasks extension

Once the extension is installed, the available tasks are shown above the marketplace items.

Add Terraform Tasks

The first task will be installing Terraform on the agent server. Select the ‘Terraform Installer’ tasks and click Add.

Add Terraform installer

After the Terraform Installer has been added as a task, click it to display the configuration on the left. By default, it will install version 0.11.11, which at the time of this post, is the latest version. There is no more configuration needed for this task.

Install Terraform

The next task will use the ‘Terraform CLI’ task. Search for it and click Add. I will use this task multiple times subsequently, therefore, I clicked Add THREE more times.

Add Terraform CLI tasks

Each of the Terraform CLI tasks that were added will need to be modified for the specific operations run in order. As a result, ‘terraform init’ will need to run first. The init CLI command within the extension has configuration to setup the backend for state storage on an Azure blob. Make sure the service account that is created for DevOps to communicate with the Azure subscription has proper access to the blob storage.

Terraform Init Configuation

My next task is to run ‘terraform validate’ against my terraform code. When the validate command is chosen from the CLI task, the task configuration options change. My terraform code requires two variables to be passed, vmcount and pass. Therefore, I need to add those variables into the command options. I am passing the variables from the build’s variables I previously set up. The secure variables file I uploaded is also selected under the ‘Variables’ section.

Terraform Validate

The next task is of course ‘terraform plan’. The settings are almost the same as validate. The only difference is the selection of the Azure subscription to deploy to.

Terraform Plan

Finally, ‘terraform apply’ needs to be run. As expected, the configuration is identical to the plan command.

Terraform Apply

Because this was primarily for testing, I chose to use the destroy command to ensure cleanup of my public cloud resources to prevent a large bill. The destroy configuration looks similar to the above tasks.

Terraform destroy

Finally, I want to make sure my tfvars file that was copied to the agent server is removed. The ‘Delete Files’ task is made for this. The $(Agent.TempDirectory) source folder needs to be entered along with the contents of ‘**’ (double asterisk).

Delete sensitive files from the agent server.

After all of these tasks are set up, manually initiate a queue of this build process and watch it deploy your desired infrastructure. It should look like the following screenshot.

A successful pipeline build

The screenshot above shows a successful build of that confirms our Terraform configuration is able to be deployed. After this, the build artifacts should collected and stored either in Azure Artifacts or on an accessible file share. A release pipeline will be made that will consume the artifacts to create a release. An example a release could look like this.

Successful Release


Once your Terraform configurations are consumed by multiple people within your organization, you should begin using version control to ensure validated configurations are being used. You can use Azure Pipelines to create a continuous integration process to build and test commits to the code repository. In addition, a full CI/CD process can be implemented when releases are added in.

As I mentioned earlier, the methods I chose to use in the build pipeline is not the only way to achieve this result. However, to get up and going, this may be the quickest method.

You could deploy Terraform configuration via Azure Pipelines as a bridge between the stage of Terraform opensource and Terraform Enterprise. Terraform Enterprise has much of this functionality built in along with other Terraform specific features that are very useful when scale has grown.

Leave a Reply

Required fields are marked *.

This site uses Akismet to reduce spam. Learn how your comment data is processed.