This series on ADF deployment management seems to be never ending and always evolving. In a previous post I shared some code that could be added to an Azure DevOps pipelines that would check for failed deployment messages. This was necessary as typically we’d not get a useful error back, and in some environments we did not have access to the Resource Group to check for deployment errors.

Now that we have moved to making deployments using linked templates for ADF this code is no longer helpful, as it returns the same top error: each linked template has its own entry in the Deployment registry. And so any errors will exist in the linked template that failed.

To solve this I’ve written a PowerShell script that will get the linked template deployment names out of the main deployment entry, and loop through those to return the error messages.

param (


    az deployment operation group list --resource-group $ResourceGroupName --name $DeploymentName --query "[?properties.provisioningState=='Failed'].properties.statusMessage.error" 
    $linked_templates_deployment = az deployment operation group list --resource-group $ResourceGroupName --name $DeploymentName --query "[].properties.targetResource.{resourceGroup:resourceGroup, resourceName: resourceName, resourceType: resourceType}"
    if ($linked_templates_deployment) {
        Write-Host "Getting details for linked template deployments from $DeploymentName"
        $linked_templates_deployment | ConvertFrom-Json | Where-Object { $_.resourceType -eq 'Microsoft.Resources/deployments' } | ForEach-Object {
            $az_deployment_operation_group_list_output = $null
            $az_deployment_operation_group_list_output = az deployment operation group list --resource-group $_.resourceGroup --name $_.resourceName --query "[?properties.provisioningState=='Failed'].properties.statusMessage.error" | ConvertFrom-Json
            if ($az_deployment_operation_group_list_output) {
                Write-Host "Getting details for deployment $($_.resourceName)"

This can then be executed by a step in the yaml pipeline.

      - task: AzureCLI@2
        displayName: Get ADF Failed Deployments
        condition: always()
          azureSubscription: "${{ parameters.azure_subscription }}"
          scriptType: pscore
          workingDirectory: $(Pipeline.Workspace)/scripts
          scriptLocation: inlineScript
          inlineScript: |
               ./getAdfFailedDeploymentOperations.ps1 -ResourceGroup $(resourceGroup.name) -DeploymentName $(adf_deployment_name)

Remember you need to have the name of the deployment set for these searches to work.