Reputation: 701
I have a template for running a terraform plan or apply depending on command parameter passed into the template.
The stage and template files looks like this (slimmed down for context).
- stage: terraform_${{ parameters.environment }}
displayName: "Stage1"
jobs:
- job: "TFPlan"
steps:
- template: ../steps/terraform-steps.yml
parameters:
command: plan
subscription: ${{ variables['Terraform.Subscription'] }}
- job: "TFApply"
variables:
changesPresent: $[ dependencies.TFPlan.outputs['Terraformplan.changesPresent'] ]
steps:
- template: ../steps/terraform-steps.yml
parameters:
command: apply
subscription: ${{ variables['Terraform.Subscription'] }}
changesPresent: $(changesPresent)
parameters:
- name: command
displayName: Terraform Command
type: string
default: plan
values:
- plan
- apply
- name: subscription
displayName: Azure Subscription
type: string
- name: changesPresent
displayName: Changes changesPresent
type: string
default: "false"
steps:
- ${{ if eq(parameters.command, 'apply') }}:
- powershell: |
Write-Host "command = ${{parameters.command}}"
Write-Host "changesPresent = ${{parameters.changesPresent}}"
Write-Host "equals commandIsApply = ${{ eq(parameters.command, 'apply') }}"
Write-Host "equals changesPresentisFalse = ${{ eq(parameters.changesPresent, 'false') }}"
Write-Host "equals changesPresentisFalse = ${{ eq(parameters.changesPresent, false) }}"
Write-Host "equals changesPresentisFalse = ${{ eq(parameters.changesPresent, False) }}"
Write-Host "equals changesPresentisTrue = ${{ eq(parameters.changesPresent, 'true') }}"
Write-Host "equals changesPresentisTrue = ${{ eq(parameters.changesPresent, true) }}"
Write-Host "equals changesPresentisTrue = ${{ eq(parameters.changesPresent, True) }}"
- ${{ if not(and(eq(parameters.command, 'apply'), eq(parameters.changesPresent, 'false'))) }}:
- task: TerraformTaskV4@4
name: Terraform${{ parameters.command }}
displayName: Terraform ${{ parameters.command }}
inputs:
provider: azurerm
command: ${{ parameters.command }}
environmentServiceNameAzureRM: ${{ parameters.subscription }}
The TerraformTaskV4@4 step has an output of changesPresent (doc). I'm trying to access this output var from the first job that runs terraform plan and pass it into the second job to determine if it needs bother to run the terraform apply depending on whether there are any changes present.
As you can see from all the debug output in the template I'm trying to verify that when changesPresent is passed into the template as a parameter it is set to the value I expect.
Strangely the following line shows a value of false:
Write-Host "changesPresent = ${{parameters.changesPresent}}"
And yet every following line that tries to confirm that value with an eq() returns a False value. This is the output I'm getting:
command = apply
changesPresent = false
equals commandIsApply = True
equals changesPresentisFalse = False
equals changesPresentisFalse = False
equals changesPresentisFalse = False
equals changesPresentisTrue = False
equals changesPresentisTrue = False
equals changesPresentisTrue = False
It correctly equates the command parameter to "apply" but not the changesPresent parameter to "false". I'm sure it has something to do with the compile/runtime/macro syntax madness but I can't figure out how to make it work. Any help much appreciated.
Upvotes: 0
Views: 175
Reputation: 13834
In the TFApply
job, both of the expressions "${{ parameters.changesPresent }}
" and "$(changesPresent)
" can output the correct values passed from the TFPlan
job.
But the following command lines always output the 'False
' result that is same as your pipeline.
Write-Host "equals parameters.changesPresent = ${{ eq(parameters.changesPresent, false) }}"
Write-Host "equals parameters.changesPresent = ${{ eq(parameters.changesPresent, False) }}"
Write-Host "equals parameters.changesPresent = ${{ eq(parameters.changesPresent, 'true') }}"
Write-Host "equals parameters.changesPresent = ${{ eq(parameters.changesPresent, true) }}"
Write-Host "equals parameters.changesPresent = ${{ eq(parameters.changesPresent, True) }}"
Write-Host "equals variables.changesPresent = ${{ eq(variables.changesPresent, 'false') }}"
Write-Host "equals variables.changesPresent = ${{ eq(variables.changesPresent, false) }}"
Write-Host "equals variables.changesPresent = ${{ eq(variables.changesPresent, False) }}"
Write-Host "equals variables.changesPresent = ${{ eq(variables.changesPresent, 'true') }}"
Write-Host "equals variables.changesPresent = ${{ eq(variables.changesPresent, true) }}"
Write-Host "equals variables.changesPresent = ${{ eq(variables.changesPresent, True) }}"
However, the following command lines can identify the correct values using the PowerShell if...else
statement.
if ("${{ parameters.changesPresent }}" -eq "true") {
Write-Host "The value of parameters.changesPresent is true."
}
else {
Write-Host "The value of parameters.changesPresent is false."
}
if ("$(changesPresent)" -eq "true") {
Write-Host "The value of variables.changesPresent is true."
}
else {
Write-Host "The value of variables.changesPresent is false."
}
Upvotes: 0
Reputation: 9208
You're trying to pass in a runtime variable as a parameter value when you call the template:
changesPresent: $(changesPresent)
This won't work. Parameter values have to be known at compile time, before the pipeline starts running at all.
I suggest you try a different approach:
parameters.changesPresent
, just refer to the variable directly @(changesPresent)
. It's accessible even within the template.changesPresent
, implement this as a task condition instead of using conditional insertion.Upvotes: 0