I am experiencing an issue with my deployment pipeline where the final ‘apply’ stage does not trigger, even though there are no explicit dependencies or conditions set to control its execution. Below is an overview of the template I use to deploy each environment:
Pipeline:
trigger:
batch: true
branches:
include:
- main
pr:
branches:
include:
- main
stages:
- template: templates/deploy.yml
parameters:
environment: Dev
- template: templates/deploy.yml
parameters:
environment: Uat
- template: templates/deploy.yml
parameters:
environment: Prd
Template:
stages:
- stage: Terraform_Plan_${{ parameters.environment }}
displayName: Plan
condition: always()
jobs:
- job: Terraform_Plan_${{ parameters.environment }}
displayName: Plan Terraform
pool: 'selfhosted'
steps:
- powershell: |
# set it to true or false
Write-Host "##vso[task.setvariable variable=anyTfChanges;isOutput=true]true"
displayName: Detect any Terraform changes
name: anyTfChanges
- stage: Any_Tf_Changes_${{ parameters.environment }}
displayName: Terraform Changes
dependsOn: Terraform_Plan_${{ parameters.environment }}
variables:
anyTfChanges: $[ stageDependencies.Terraform_Plan_${{ parameters.environment }}.Terraform_Plan_${{ parameters.environment }}.outputs['anyTfChanges.anyTfChanges'] ]
condition: and(eq('true', 'true'), eq(dependencies.Terraform_Plan_${{ parameters.environment }}.outputs['Terraform_Plan_${{ parameters.environment }}.anyTfChanges.anyTfChanges'], 'true'))
jobs:
- job: Terraform_Changes_${{ parameters.environment }}
displayName: Detect Terraform Changes
steps:
- checkout: none
- powershell: |
Write-Host "hello world"
displayName: Terraform changes detected
- stage: Terraform_Apply_${{ parameters.environment }}
displayName: Apply ${{ parameters.environment }}
jobs:
- deployment: Apply
environment: ${{ parameters.environmentDisplayName }}
displayName: Apply Terraform
pool: 'selfhosted'
strategy:
runOnce:
deploy:
steps:
- checkout: self
- script: |
Write-Host "hello world"
Despite the configuration, the last ‘apply’ stage does not run in last prd
stages:
Does anyone know why this might be happening or what I might be missing in the configuration that prevents this stage from running?
Thanks in advance for any help or insights!
2
Answers
Refer this MS doc: Specify conditions, it says: The default condition for a stage is
condition: succeeded()
If any of the parent stages do not succeed, then all the child stages are skipped, except for those where conditions are specified and evaluate to true. That’s why in your case, the stage "Plan" always runs, the stage "Terraform Changes" runs whenever "anyTfChanges" is true, the last stage "Apply" runs only when all the previous stages have succeeded as there is no condition specified. Since in your case, not all the previous stages are green, the final "Apply" stage is getting skipped..
So try adding the same condition
condition: and(eq('true', 'true'), eq(dependencies.Terraform_Plan_${{ parameters.environment }}.outputs['Terraform_Plan_${{ parameters.environment }}.anyTfChanges.anyTfChanges'], 'true'))
in the "Apply" stage as well, as shown below:There seems to be some misunderstandings on the YAML pipeline default behaviors. Please note that,
Apply ${{ parameters.environment }}
, by default, it depends on the stage just before it in the YAML file.Apply ${{ parameters.environment }}
, it will use the default condition, which means this stage runs if all direct and indirect dependencies have succeeded, as if you specifiedcondition: succeeded()
.condition
property for a stage / job / step, you overwrite its defaultcondition: succeeded()
. Therefore, you may consider adding the same condition in stageApply ${{ parameters.environment }}
as that you defined for stageAny_Tf_Changes_${{ parameters.environment }}
.Apply ${{ parameters.environment }}
when writing your own conditions, since overwriting the default condition can lead to your stage running even if the build is cancelled or failed.With those being said, if your actual expectation is to run the stage
Terraform_Apply_${{ parameters.environment }}
only if the stageAny_Tf_Changes_${{ parameters.environment }}
is succeeded. You can try adding the expressioneq(dependencies.Any_Tf_Changes_${{ parameters.environment }}.result, 'Succeeded')
in the condition of the apply stage. Here is the part of stageTerraform_Apply_${{ parameters.environment }}
of the YAML pipeline for your reference.