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
- Build all the services
- 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 Answer
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
- 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=""
$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 }}