Published

- 3 min read

Using Azure Pipeline Parameters & Variables in Terraform

img of Using Azure Pipeline Parameters & Variables in Terraform

This post showcases how to set up Azure pipeline parameters or variables on a pipeline and pass them to Terraform as variables. It covers string and boolean types. In most cases, a tfvars file is used, but there may be a use case when just one variable is needed, and this is where Azure pipeline parameters/variables come in handy.

Prerequisites

This assumes basic knowledge of Terraform and Azure pipelines. Your Azure DevOps account should be set up with a service connection that the Terraform task can use, and a resource group and storage account should be available for the Terraform backend.

Initial Terraform Setup

This is a basic example showing a simple setup with a single resource being created: an Azure resource group. The resource group name is provided via a variable.

main.tf

   terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.71.0"
    }
  }

  backend "azurerm" {
  }

  required_version = ">= 1.1.0"
}

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "rg_bool_test" {
  name     = var.resource_group_name
  location = "West Europe"
}

variables.tf

   variable "resource_group_name" {
  type = string
  description = "This is the name for the resource group containing all resources created."
}

Initial Azure Pipelines Setup

   trigger: none

parameters:
  - name: resourceGroupName
    type: string

stages:
  - stage: DeployTf
    jobs:
      - job: deploy
        steps:
          - task: TerraformInstaller@1
            displayName: 'Terraform Install'
            inputs:
              terraformVersion: 'latest'

          - task: TerraformTaskV4@4
            displayName: 'Terraform Init'
            inputs:
              provider: 'azurerm'
              command: 'init'
              backendServiceArm: 'tf-service-connection'
              backendAzureRmResourceGroupName: 'tfstate'
              backendAzureRmStorageAccountName: 'storacctfstate'
              backendAzureRmContainerName: 'booltest'
              backendAzureRmKey: 'terraform.tfstate'

          - task: TerraformTaskV4@4
            displayName: 'Terraform Validate'
            inputs:
              provider: 'azurerm'
              command: 'validate'

          - task: TerraformTaskV4@4
            displayName: 'Terraform Plan'
            inputs:
              provider: 'azurerm'
              command: 'plan'
              environmentServiceNameAzureRM: 'tf-service-connection'
              commandOptions: '-out main.tfplan -var resource_group_name=${{ parameters.resourceGroupName }}'

          - task: TerraformTaskV4@4
            displayName: 'Terraform Apply'
            inputs:
              command: 'apply'
              provider: 'azurerm'
              workingDirectory: '$(Build.SourcesDirectory)'
              environmentServiceNameAzureRM: 'tf-service-connection'
              commandOptions: '-auto-approve -input=false main.tfplan'

Using Azure Pipeline Parameters

As you can see, there is a pipeline parameter declared as follows:

   parameters:
  - name: resourceGroupName
    type: string

Since there is no default value, it is a required parameter:

Pipeline Run.

In the plan, this commandOptions snippet using ‘-var’ is used to pass the Azure pipelines parameter to Terraform:

   -var resource_group_name=${{ parameters.resourceGroupName }}

Using Azure pipeline Variables

Adjust the existing pipeline to define a variable:

   variables:
  - name: resourceGroupName
    value: 'test'

The usage just needs a syntax adjustment for using variables:

   -var resource_group_name=$(resourceGroupName)

Gotcha Using Boolean Type

For any use case that requires a boolean pipeline parameter to be passed to Terraform as a variable, there is a gotcha. Let’s see this with some minor additions to the existing code, using a flag to enable/disable the resource group creation:

variables.tf

   variable "is_create_enabled" {
  type = boolean
  default = false
  description = "This flag is to enable/disable creation of resources."
}

main.tf

   resource "azurerm_resource_group" "rg_bool_test" {
  count    = var.is_created_enabled ? 1 : 0
  name     = var.resource_group_name
  location = "West Europe"
}

Pipeline

Add a boolean parameter:

   parameters:
  - name: isCreateEnabled
    displayName: 'Is Create Enabled'
    type: boolean

Pass this parameter to Terraform using -var:

   -var is_create_enabled=${{ parameters.isCreateEnabled }}'

Gotcha

When triggering the updated pipeline manually, you will face the following error:

Terraform Bool Fail Error.

The error message a bool is required; to convert from string, use lowercase “false” gives us a good indication on where the error comes from. Let’s add a simple task to show what the string value of isCreateEnabled is:

   - task: Bash@3
  inputs:
    targetType: 'inline'
    script: |
      echo "Boolean value is: ${{ parameters.isCreateEnabled }}"

The output is: Boolean value is: False

There is a simple fix for this, using the built-in lower function, like so:

   -var is_create_enabled=${{ lower(parameters.isCreateEnabled) }}

This straightforward approach allows you to efficiently use Azure Pipeline parameters and variables as Terraform variables, I hope this helps if you run into a similar use case.