azureazure-devopsazure-pipelinesazure-blob-storage

Passing Variable Between Stages in Azure DevOps Pipeline


I have a build pipeline that needs to create a URL with a Shared Access Signature (see: SAS or authentication key) for access to a ZIP file downstream in the pipeline. I am able to create the URL and SAS key just fine but getting it to another stage isn't working.

The process is documented fairly well here but I must be missing something.

I've included the full pipeline here for context, but the main logic is in the Generate SAS URL for the artifact task and Deployment to prod job:

trigger:
- main

variables:
  - group: xyz

pool:
  name: Default

stages:
- stage: build
  displayName: Build the application

  jobs:
    - job: build
      displayName: Build
      steps:
        - task: UseDotNet@2
          inputs:
            version: 8.x
        - task: DotNetCoreCLI@2
          displayName: Build Function App
          inputs:
            command: 'build'
            projects: |
              $(System.DefaultWorkingDirectory)/src/AzureFunctions/AzureFunctions.csproj
            arguments: --output $(System.DefaultWorkingDirectory)/function-package --configuration Release

        - task: ArchiveFiles@2
          displayName: 'Archive files'
          inputs:
            rootFolderOrFile: '$(System.DefaultWorkingDirectory)/function-package'
            includeRootFolder: false
            archiveType: zip
            archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildNumber).zip
            replaceExistingArchive: true

        - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildNumber).zip
          artifact: function-package

        - task: AzureCLI@2
          displayName: 'Upload artifact to Azure Storage'
          inputs:
            azureSubscription: '<secret>'
            scriptType: 'bash'
            scriptLocation: 'inlineScript'
            inlineScript: |
              storage_key=$(az storage account keys list --resource-group <secret> --account-name <secret> --query '[0].value' --output tsv)
              az storage blob upload \
                --account-name <secret> \
                --container-name function-artifacts/<secret> \
                --name $(Build.BuildNumber).zip \
                --file $(Build.ArtifactStagingDirectory)/$(Build.BuildNumber).zip \
                --account-key $storage_key

        - task: AzureCLI@2
          displayName: 'Generate SAS URL for the artifact'
          inputs:
            azureSubscription: '<secret>'
            scriptType: 'bash'
            scriptLocation: 'inlineScript'
            inlineScript: |
              storage_key=$(az storage account keys list --resource-group <secret> --account-name <secret> --query '[0].value' --output tsv)
              sas_url=$(az storage blob generate-sas \
                --account-name <secret> \
                --container-name function-artifacts/<secret> \
                --name $(Build.BuildNumber).zip \
                --permissions r \
                --expiry $(date -u -d "1 year" '+%Y-%m-%dT%H:%MZ') \
                --account-key $storage_key \
                --output tsv)
              echo "##vso[task.setvariable variable=ArtifactSasUrl;isOutput=true]https://<secret>.blob.core.windows.net/function-artifacts/<secret>/$(Build.BuildNumber).zip?$sas_url"

        - publish: $(System.DefaultWorkingDirectory)/build/bicep
          artifact: bicep-package

- stage: deployment_prod
  dependsOn: build
  displayName: Deployment to prod
  variables:
    ArtifactSasUrl: $[dependencies.build.outputs['build.ArtifactSasUrl']]
  jobs:
    - template: deployment.yaml
      parameters:
        Environment: 'prod'
        StorageAccount: $(StorageAccount)
        LoftwareDb: $(<secretDb>)
        AppServicePlanResourceId: $(AppServicePlanResourceId)
        ResourceGroupName: '<secret>'
        ServiceConnectionName: '<secret>'
        SubscriptionId: '<secret>'
        ArtifactUrl: '$(ArtifactSasUrl)'

I have a step in a downstream process that prints out the SAS URL and it's empty (no error, just empty).


Solution

  • I simplified your code to make it easier. Please take a close look at the color area I have highlighted.

    You should refer the across stage variable from the format stageDependencies.STAGE.JOB.outputs['TASK.VARIABLE']. docs

    pipeline.yml

    stages:
    - stage: buildStage
      displayName: Build the application
    
      jobs:
        - job: buildJob
          displayName: Build
          steps:
            - task: AzureCLI@2
              displayName: 'Generate SAS URL for the artifact'
              name: setVariableStep
              inputs:
                azureSubscription: 'DevOpsSub1Connection-Test'
                scriptType: 'bash'
                scriptLocation: 'inlineScript'
                inlineScript: |
                  storage_key='storage_key'
                  sas_url='sa_sas_url'
                  echo "##vso[task.setvariable variable=ArtifactSasUrl;isOutput=true]https://test.blob.core.windows.net/function-artifacts/test/$(Build.BuildNumber).zip?$sas_url"
    
            - script: echo "print $(setVariableStep.ArtifactSasUrl)"
    
    - stage: deployment_prod
      dependsOn: buildStage
      displayName: Deployment to prod
      variables:
        ArtifactSasUrl: $[stageDependencies.buildStage.buildJob.outputs['setVariableStep.ArtifactSasUrl']]
      jobs:
      - job:
        steps:
        - script: echo "print $(ArtifactSasUrl)"
    

    enter image description here

    my test result:

    enter image description here