1
votes

I have a scenario where I need to pass a variable between two pipelines and have that variable be evaluated at compile time on the destination pipeline.

I have a build pipeline that can either

  1. Build all the services
  2. Build just one of the services

The build pipeline needs to remain independent of the deploy pipeline due to limitations of Azure Pipelines. The trigger batching feature currently does not support running new builds unless the first build has 100% completed the pipeline. We have manual approvals so this is a no-go.

I have a deploy pipeline that ideally should support being manually triggered using parameters to pass "AllServices" or the name of the individual service the user wants deployed AND support being triggered by the resource pipeline during an automated build.

The issue I am struggling with is how does the deployment pipeline get information sent to it during the trigger or can it be set somewhere to be read at compile time? These variables are only available at runtime

resources.pipeline.<Alias>.projectName
resources.pipeline.<Alias>.projectID
resources.pipeline.<Alias>.pipelineName
resources.pipeline.<Alias>.pipelineID
resources.pipeline.<Alias>.runName
resources.pipeline.<Alias>.runID
resources.pipeline.<Alias>.runURI
resources.pipeline.<Alias>.sourceBranch
resources.pipeline.<Alias>.sourceCommit
resources.pipeline.<Alias>.sourceProvider
resources.pipeline.<Alias>.requestedFor
resources.pipeline.<Alias>.requestedForID

Compile time vs runtime is important here because I am using the ${{ }}: syntax to control which parameters to inject into the deploy template.

resources:
  pipelines:
  - pipeline: services_build
    source: Services.Build
    trigger: true

name: Services-$(Date:yyyyMMdd).$(Rev:r)
trigger: none
pr: none

stages:
- template: ../templates/deploy_the_services.yaml
  parameters:
    ${{ if startsWith(resources.pipeline.services_build.pipelineName, 'AllServices') }}:
      services:
        - Service1
        - Service2
        - Service3
    ${{ if startsWith(resources.pipeline.services_build.pipelineName, 'Service1') }}:
      services:
        - Service1

deploy_the_services.yaml

parameters:
  - name: services
    type: object

stages:
  - stage: EnvironmentA
    displayName: 'Push to EnvironmentA'
    jobs:
    - template: ../templates/deploy.appservice.yaml
      parameters:
        environment: 'EnvironmentA'
        services: ${{ parameters.services }}
  
  ... # Many more stages after this

deploy.appservice.yaml

parameters:
- name: services
  type: object
- name: environment
  type: string

jobs:
# This is the important part.  This is an array of services to iterate over
- ${{ each service in parameters.services }}:
    - deployment:
      displayName: 'Deploy ${{ service.name }}'
      environment: '${{ parameters.environment }}'
      variables:
        - group: '${{ service.name }}'
        - group: '${{ parameters.environment }}-secrets'
      pool:
        vmImage: 'windows-2019'
      strategy:
        runOnce:
          deploy:
            steps:
            - powershell: |
                # Do the stuff and things
1

1 Answers

1
votes

I checked your problem further, if you want deployment pipeline get information sent to it during the trigger, these variables are only available at runtime. You can try to use pipeline run rest api to pass variables.

You can check the following steps:

1.Define Runtime parameters in your pipeline to save the passed variables. See below:

parameters:
-name: contentKey
   displayName: Pool Image
   default: contentDefaultValue
  1. Then You can use powershell task to run rest api in your pipeline and provide the templateParameters in the request body to override the Runtime parameters defined in your pipeline.

See below:

 {
      "templateParameters":{
         "contentKey": "contentValue"
      }
    }

Below is a demo I tested, you can also refer to this:

In yaml pipeline file. You can define your parameter as below:

parameters:
- name: contentKey
  displayName: pass variables
  default: variable1

The powershell task in your yaml as below:

- powershell: |
     $token = "PAT"
     $url="https://dev.azure.com/{organization}/{project}/_apis/pipelines/{pipelineId}/runs?api-version=6.1-preview.1"
     $token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))
     $body = "{
        `"templateParameters`":{
        `"contentKey`": `"contentValue`"
        }
        }"
     $response3 = Invoke-RestMethod -Uri $url -Headers @{Authorization = "Basic $token"} -Method Post -Body $body -ContentType application/json

Then you can access the parameter in the bash task like below:

echo ${{ parameters.contentKey }}