Search code examples
azure-devopscontinuous-integrationterraformpipeline

Pass Azure Devops pipeline variable to template without it getting set to the literal value


I have a pipeline with a template that plans terraform using TerraformTestV1@0

I'm currently setting a variable depending on the branch and want that to set the variable group it uses but it's setting the literal value and trying to find a variable group with that value. E.G It's searching for $(variable group) instead of transforming.

I've tried using $[variables.countryCode] and $(countryCode) but get the same outcome. I'm also using another variable in the same way but this one is getting transformed.

I know the countryCode variable is also getting set because I have a powershell task beforehand I tested that shows the output I was expecting.

Here's the pipeline I currently have setup

deploy.yml

name: $(BuildDefinitionName)_1.0$(Rev:.r)

trigger:
  tags:
    include:
    - 'refs/tags/uk-*'
    - 'refs/tags/us-*'
    - 'refs/tags/es-*'

pool: Default

variables:
- name: countryCode
  ${{ if startsWith(variables['Build.SourceBranch'], 'refs/tags/es-') }}:
    value: es
  ${{ if startsWith(variables['Build.SourceBranch'], 'refs/tags/us-') }}:
    value: us
  ${{ if startsWith(variables['Build.SourceBranch'], 'refs/tags/uk-') }}:
    value: uk
- name: statefilename
  value: pipelinetest 

resources:
  repositories:
    - repository: templates
      type: git
      name: MyTemplateRepo

stages :
  - stage:
    jobs:
      - job: test
        steps:
              - task: PowerShell@2
                displayName: Split_Tag
                continueOnError: false
                inputs:
                  targetType: inline
                  script: | 
                    Write-host $(countryCode)

  - stage: Plan_Dev
    jobs:
    - template: terraform-plan2.yml@templates
      parameters:
        servicePrincipal: Development $[variables.countryCode]
        stateFileName: "$(statefilename).tfstate"
        variableGroup: Terraform $[variables.countryCode] Development Environment
        terraformVersion: '0.14.6'
        condition: ""

template:

parameters:
- name: 'servicePrincipal'
  default: 'CI Subscription'
  type: string
- name: 'stateFileName'
  type: string
- name: 'variableGroup'
  type: string
- name: 'condition'
  type: string
- name: 'terraformVersion'
  type: string
  default: "0.14.6"

jobs:
  - job: TerraformPlan
    condition: ${{ parameters.condition }}
    variables:
      - group: ${{ parameters.variableGroup }}
    steps:
          - task: TerraformInstaller@0
            displayName: Terraform Install
            inputs:
                terraformVersion: ${{ parameters.terraformVersion }}
          - task: replacetokens@3
            inputs:
                targetFiles: '**/*.tfvars'
                encoding: 'auto'
                writeBOM: true
                actionOnMissing: 'warn'
                keepToken: false
                tokenPrefix: '#{'
                tokenSuffix: '}'
                useLegacyPattern: false
                enableTransforms: false
                enableTelemetry: true
          - task: TerraformTaskV1@0
            displayName: Terraform init
            inputs:
                provider: 'azurerm'
                command: 'init'
                commandOptions: '-upgrade'
                backendServiceArm: ${{ parameters.servicePrincipal }}
                backendAzureRmResourceGroupName: $(backendResourceGroup)
                backendAzureRmStorageAccountName: $(backendStorageAccount)
                backendAzureRmContainerName: $(backendContainer)
                backendAzureRmKey: "$(short_location).$(tenant).$(short_environment).${{ parameters.stateFileName }}"
          - task: TerraformTaskV1@0
            displayName: Terraform Validate
            inputs:
                provider: 'azurerm'
                command: 'validate'
                backendAzureRmKey: ${{ parameters.servicePrincipal }}
          - task: TerraformTaskV1@0
            displayName: Terraform Plan
            inputs:
                provider: 'azurerm'
                command: 'plan'
                commandOptions: '-var-file="devops.tfvars"'
                environmentServiceNameAzureRM: ${{ parameters.servicePrincipal }}

This is the error I'm getting: The pipeline is not valid. Job TerraformPlan: Variable group Terraform $(countryCode) Development Environment could not be found. The variable group does not exist or has not been authorized for use.

Any ideas why this isn't getting transformed?


Solution

  • You're using the wrong syntax to reference variables.

    $[] is for runtime variables, which means variables that are set absolutely last in the process, after the YAML template is compiled. Unless you are specifically dealing with runtime variables, the safe assumption is that that syntax is incorrect.

    The syntax you're looking for is ${{ variables.countryCode }}, or ${{ variables['countryCode'] }}. Any one of those should work. Compile-time variable references can be a bit tricky... some of those work in some circumstances, but not in others.

    I've found the most consistently reliable syntax is ${{ variable.whatever }}.