M. Pheles
M. Pheles

Reputation: 33

How to access "deploymentOutputs" from AzureResourceManagerTemplateDeployment (@3) task from Azure DevOps YAML pipeline?

I am developing YAML pipeline which is simply deploying a HUB resource based on a main.bicep file (there's ONLY azure ADF deploy through it for now) saved in my Azure DevOps repo. However, I need to have access to "output" of the deployment of the bicep - I need for instance the IDs of some of the Azure Resources which get deployed. (also the deployment works without issues >> at the END I do have the ADF deployed)

Here is the code: stages:

#  DEPLOYING INFRASTRUCTURE - HUB
  - stage: DeployHub
    displayName: Deploy Hub Infrastructure
    jobs:
      - deployment: DeployHub
        displayName: Deploy Hub Infrastructure
        environment: '$(testEnvironment)' #used for the manual approval conditions
        strategy:
         runOnce:
          deploy:
            steps:
            # the checkout will enable the use of "git diff" as to see which files have been modified in the latest commit at some point
            - checkout: git://${{ variables.my_org }}/my_project@refs/heads/feature_branch_01

          # Actual deployment of the resources - HUB
            - task: AzureResourceManagerTemplateDeployment@3
              name: ARM_Template_Deployment_HUB
              displayName: 'Bicep Deployment Task HUB'
              inputs:
                deploymentScope: 'Resource Group'
                azureResourceManagerConnection: '$(serviceConnection)'
                action: 'Create Or Update Resource Group'
                resourceGroupName: '$(rgTesting)'
                location: 'some_location'
                templateLocation: 'Linked artifact'
                csmFile: '$(Build.SourcesDirectory)/$(bicepFilePathHUB_Test)'
                deploymentMode: Incremental
                deploymentOutputs: 'armOutputsHUB'

So the question is:

  1. How to access the armOutputsHUB?
  2. Does it matter if I access it within the same JOB, Stage?
  3. Where is it saved? - I read that all deployment type of jobs are saved in: "Deployment jobs use the $(Pipeline.Workspace) system variable." Source: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/deployment-jobs?view=azure-devops However, I still couldn't find variable called 'armOutputsHUB'

What I have tried and it did NOT work:

  1. Within the same job as next task:
            - task: PowerShell@2
              displayName: 'Parse ARM deploymentOutputs'
              env:
                ARM_OUTPUTS: $(armOutputsHUB)
              inputs:
                targetType: 'inline'
                errorActionPreference: continue
                workingDirectory: '$(Pipeline.Workspace)' #default is "$(Build.SourcesDirectory)"
                pwsh: true
                script: |
                  Write-Host "armOutputsHUB = $armOutputsHUB" # >>nothing inside
                  Write-Host "armOutputsHUB = $($armOutputsHUB)" # >> nothing inside
                  Write-Host "armOutputsHUB = $($ARM_Template_Deployment_HUB.armOutputsHUB)" # >> nothing inside

                  $outputsObject = $env:ARM_OUTPUTS | ConvertFrom-Json
                  # error: Conversion from JSON failed with error: Unexpected character encountered while parsing value: $. Path '', line 0, position 0.
                  Write-Host "outputsObject = $($outputsObject)"  # >>nothing inside
                  Write-Host "outputsObject = $outputsObject"  # >>nothing insi

Any ideas or solutions / code for me to test will be greatly appreciated!!

Upvotes: 3

Views: 3636

Answers (2)

Palec
Palec

Reputation: 13551

Each output is processed by JSON.stringify() by default. The AzureResourceManagerTemplateDeployment@3 task allows disabling this processing via the parameter useWithoutJSON: true, called "Use individual output values without JSON.Stringify applied" in the UI.

This is available in Azure DevOps Services and Azure DevOps Server 2022u1, but not yet in Azure DevOps Server 2022.0.1 (AzureDevOpsServer_20230418.1). There, the parameter may be passed but it has no effect.

When deploymentOutputs is specified, not only is the variable specified via the parameter set to the JSON-serialized outputs object, but each primitive value inside the outputs object gets an extra variable whose name is in the format {deploymentOutputs}.{path.to.the.value}. For primitive outputs, you can get the value as $({deploymentOutputs}.{outputName}.value), for arrays and objects, the property names and indexes are further steps in the path: $({deploymentOutputs}.{outputName}.value.{index}) or $({deploymentOutputs}.{outputName}.value.{propertyName})

Upvotes: 1

GordonBy
GordonBy

Reputation: 3397

I've found a nice sample pipeline on GitHub for you. It's quite similar to some of your examples but the use of string quotes might be what you're missing.

The pipeline


- task: PowerShell@2
    name: 'SetDeploymentOutputVariables'
    displayName: 'Set Deployment Output Variables'
    inputs:
      targetType: inline
      script: |
        $armOutputObj = '$(deploymentOutputs)' | ConvertFrom-Json
        $armOutputObj.PSObject.Properties | ForEach-Object {
          $keyname = $_.Name
          $value = $_.Value.value

          # Creates a standard pipeline variable
          Write-Output "##vso[task.setvariable variable=$keyName;issecret=true]$value"

          # Display keys in pipeline
          Write-Output "output variable: $keyName"
        }
      pwsh: true

Upvotes: 3

Related Questions