For our Terraform Deployment, we use an Azure DevOps pipeline that has 3 stages:
For the apply stage we use a deployment job with an environment that has a manual approval (check). What we would like to have is "skipping" the apply and test stage, if the plan stage has shows no changes. Therefore we try to use the following yaml configuration for the apply stage:
- stage: ApplyShared
dependsOn: PlanShared
jobs:
- job: CheckSharedChanges
steps:
- task: DownloadPipelineArtifact@2
inputs:
artifactName: TerraformBuild
downloadPath: $(System.DefaultWorkingDirectory)
- bash: |
# using a file for indicating changes in TF plan, since
# you cannot pass variables between stages in Azure DevOps
if [ -f ".shared-changes" ]; then
echo '##vso[task.setvariable variable=shared_changes]yes'
fi
name: Check
- deployment: ApplyShared
dependsOn: CheckSharedChanges
# this condition seems to be ignored, if there is a manual
# approval on the stage
condition: eq(dependencies.CheckSharedChanges.outputs['Check.shared_env'], 'yes')
displayName: 'Apply - shared'
# we configured a manual approval (check) for this environment,
# so the pipeline stops and asks for an operator to approve the deployment
environment: 'infra-shared'
According to this issue on the MS Developer Community, a condition on a stage with an approval is not checked before the approval, so the approach does not work.
My question is: do you know any other way to implement this?
⚠Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
@michaellihs Thank you for the question.
Unfortunately at this time we can only provide support for documentation examples only.
Moving forward you will need to either provide an article example to be fixed/improved, or submit this as an issue to the Azure DevOps community for feedback from the product team.
Or, for additional support options, see:
For anyone finding this issue, having problems, this is how I made it work:
On the STAGE:
condition: eq(dependencies.Build_zip_plan.outputs['Build_portal_zip_files_terraform_plan.Check_Terraform_Plan.TFChangesPending'], 'yes')
I never got stageDependencies to work, but dependencies work just fine.
Here is a script I use as a step to analyze the TF plan in order to generate the above TFChangesPending variable:
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[String] $TfPlan
)
if(!(Test-Path $TfPlan)) {
Write-Host "##[error] :: Plan file '$TfPlan' not found"
exit 1;
}
Push-Location (Split-Path $TfPlan -Parent)
$TfPlanJson = terraform show -json (Split-Path $TfPlan -Leaf)
$TfPlanParsed = $TfPlanJson | ConvertFrom-Json
$numPendingChanges = (
$TfPlanParsed.resource_changes |
Where-Object {
$_.change | Where-Object {
$_.actions -contains "update" -or
$_.actions -contains "create" -or
$_.actions -contains "delete"
}
} |
Measure-Object
).Count
if($numPendingChanges -gt 0) {
Write-Verbose "Found $numPendingChanges pending changes in tfplan" -Verbose
Write-Host "##vso[task.setvariable variable=TFChangesPending;isOutput=true]yes"
} else {
Write-Verbose "Found no pending changes in tfplan" -Verbose
Write-Host "##vso[task.setvariable variable=TFChangesPending;isOutput=true]no"
}
Pop-Location