admin管理员组文章数量:1312888
In my multi-stage YAML pipeline, we use deployment jobs that uses an Azure Pipeline Environment that has a Invoke Azure Function check in the Approvals and Checks. We're using the asynchronous model, where the function app is responsible for issuing the approval based on our business criteria. The function app callback works well but we're having issues with providing stage-specific configuration.
In the "Invoke Azure Function" check, we provide a JSON payload that contains variables defined in macro syntax. I'm seeing the following behaviour with our payload:
- pre-defined variables work as expected
- global pipeline variables are resolved correctly
- variables that are scoped to the stage do not get resolved
# POST BODY of Invoke Azure Function:
{
# these values are fine because they're all predefined variables
"projectId": "$(system.TeamProjectId)",
"hubName": "$(system.HostType)",
"planId": "$(system.PlanId)",
"buildId": "$(build.BuildId)",
"jobId": "$(system.JobId)",
"timelineId": "$(system.TimelineId)",
"taskInstanceId": "$(system.TaskInstanceId)",
"taskInstanceName": "$(system.TaskInstanceName)",
# this variable works because it's defined at the root level of the pipeline
"deploymentType": "$(PipelineDescription)",
# these variables do not work because they're defined in the stage
"customer": "$(Customer)",
"environment": "$(Environment)"
}
Although I don't believe the structure of the pipeline is relevant, for visibility sake, post-compilation our pipeline looks something like this:
trigger: none
variables:
pipelineDescription: "Maintenance Release"
stages:
- stage: build
...
- stage: deploy_qa
dependsOn: [ build ]
variables:
Customer: "Internal"
Environment: "QA Lab"
jobs:
- deployment: deploy_qa
environment: qa
strategy:
runOnce:
deploy:
steps:
- ....
- stage: deploy_customer1_test
dependsOn: [ build ]
variables:
Customer: "Customer 1"
Environment: "Test"
jobs:
- deployment: deploy_customer1_test
environment: customer1_test
strategy:
runOnce:
deploy:
steps:
- ....
- stage: ...
When the pipeline runs, the payload that is sent to the function app looks like:
Request body: {
"projectId": "<guid>",
"hubName": "checks",
"planId": "553d1a03-abcf-55d9-8a1b-270cb656a2fe",
"buildId": "2066",
"jobId": "5f551683-56b4-55d5-de67-f7114e5b3c79",
"timelineId": "553d1a03-abcf-55d9-8a1b-270cb656a2fe",
"taskInstanceId": "6b8648fe-fcd2-5c33-fe67-eba2c9dd8146",
"taskInstanceName": "AzureFunction0",
"deploymentType": "Maintenance Release",
"customer": "$(Customer)",
"environment": "$(Environment)"
}
Although our pipeline has the values defined, it appears as though the check does not evaluate or include the variables from the stage.
I have discovered that it is possible to link the check to a variable group, which works. However, as we have hundreds of environments and existing YAML variable definitions for each, we'd prefer to keep things in source, avoid duplication and in general avoid using variable groups wherever possible.
Any thoughts on how to resolve these values? For example a REST API that I can use to evaluate the missing variables?
In my multi-stage YAML pipeline, we use deployment jobs that uses an Azure Pipeline Environment that has a Invoke Azure Function check in the Approvals and Checks. We're using the asynchronous model, where the function app is responsible for issuing the approval based on our business criteria. The function app callback works well but we're having issues with providing stage-specific configuration.
In the "Invoke Azure Function" check, we provide a JSON payload that contains variables defined in macro syntax. I'm seeing the following behaviour with our payload:
- pre-defined variables work as expected
- global pipeline variables are resolved correctly
- variables that are scoped to the stage do not get resolved
# POST BODY of Invoke Azure Function:
{
# these values are fine because they're all predefined variables
"projectId": "$(system.TeamProjectId)",
"hubName": "$(system.HostType)",
"planId": "$(system.PlanId)",
"buildId": "$(build.BuildId)",
"jobId": "$(system.JobId)",
"timelineId": "$(system.TimelineId)",
"taskInstanceId": "$(system.TaskInstanceId)",
"taskInstanceName": "$(system.TaskInstanceName)",
# this variable works because it's defined at the root level of the pipeline
"deploymentType": "$(PipelineDescription)",
# these variables do not work because they're defined in the stage
"customer": "$(Customer)",
"environment": "$(Environment)"
}
Although I don't believe the structure of the pipeline is relevant, for visibility sake, post-compilation our pipeline looks something like this:
trigger: none
variables:
pipelineDescription: "Maintenance Release"
stages:
- stage: build
...
- stage: deploy_qa
dependsOn: [ build ]
variables:
Customer: "Internal"
Environment: "QA Lab"
jobs:
- deployment: deploy_qa
environment: qa
strategy:
runOnce:
deploy:
steps:
- ....
- stage: deploy_customer1_test
dependsOn: [ build ]
variables:
Customer: "Customer 1"
Environment: "Test"
jobs:
- deployment: deploy_customer1_test
environment: customer1_test
strategy:
runOnce:
deploy:
steps:
- ....
- stage: ...
When the pipeline runs, the payload that is sent to the function app looks like:
Request body: {
"projectId": "<guid>",
"hubName": "checks",
"planId": "553d1a03-abcf-55d9-8a1b-270cb656a2fe",
"buildId": "2066",
"jobId": "5f551683-56b4-55d5-de67-f7114e5b3c79",
"timelineId": "553d1a03-abcf-55d9-8a1b-270cb656a2fe",
"taskInstanceId": "6b8648fe-fcd2-5c33-fe67-eba2c9dd8146",
"taskInstanceName": "AzureFunction0",
"deploymentType": "Maintenance Release",
"customer": "$(Customer)",
"environment": "$(Environment)"
}
Although our pipeline has the values defined, it appears as though the check does not evaluate or include the variables from the stage.
I have discovered that it is possible to link the check to a variable group, which works. However, as we have hundreds of environments and existing YAML variable definitions for each, we'd prefer to keep things in source, avoid duplication and in general avoid using variable groups wherever possible.
Any thoughts on how to resolve these values? For example a REST API that I can use to evaluate the missing variables?
Share Improve this question edited Feb 1 at 7:31 Daniel Mann 59.1k13 gold badges105 silver badges127 bronze badges Recognized by CI/CD Collective asked Jan 31 at 21:20 bryanbcookbryanbcook 18.4k2 gold badges47 silver badges79 bronze badges 11 | Show 6 more comments1 Answer
Reset to default 0I have tried several variations to find a solution for this, and have found one that might work for you. I agree that it does seem like the stage variables should be in scope at the time the function is being triggered, but I could not find any way to access them. Here is a workaround.
Proposed solution
Keeping in mind your statement here we'd prefer to keep things in source, avoid duplication and in general avoid using variable groups wherever possible.
, the solution I found was that you are able to access the stage name via the predefined variable $(System.StageName)
. So, if you were to rename your stage names to include the two variables you are trying to reference, your function could programmatically split these for use.
POST BODY of Invoke Azure Function:
{
# these values are fine because they're all predefined variables
"projectId": "$(system.TeamProjectId)",
"hubName": "$(system.HostType)",
"planId": "$(system.PlanId)",
"buildId": "$(build.BuildId)",
"jobId": "$(system.JobId)",
"timelineId": "$(system.TimelineId)",
"taskInstanceId": "$(system.TaskInstanceId)",
"taskInstanceName": "$(system.TaskInstanceName)",
# this variable works because it's defined at the root level of the pipeline
"deploymentType": "$(PipelineDescription)",
# these are unobtainable
"customer": "$(Customer)",
"environment": "$(Environment)",
# NEW PROPOSED VARIABLE
"stageName": "$(system.StageName)"
}
Example .yaml snippet (edited from your question):
- stage: deploy_qa-internal-qalab # stageName is accessible in invoke function
dependsOn: [ build ]
variables:
Customer: "Internal" # variable not accessible in invoke function
Environment: "QA Lab" # variable not accessible in invoke function
jobs:
- deployment: deploy_qa
environment: qa
strategy:
runOnce:
deploy:
steps:
- ....
Example request body (edited from your question):
Request body: {
"projectId": "<guid>",
"hubName": "checks",
"planId": "553d1a03-abcf-55d9-8a1b-270cb656a2fe",
"buildId": "2066",
"jobId": "5f551683-56b4-55d5-de67-f7114e5b3c79",
"timelineId": "553d1a03-abcf-55d9-8a1b-270cb656a2fe",
"taskInstanceId": "6b8648fe-fcd2-5c33-fe67-eba2c9dd8146",
"taskInstanceName": "AzureFunction0",
"deploymentType": "Maintenance Release",
"stageName": "deploy_qa-internal-qalab", # this is new
"customer": "$(Customer)",
"environment": "$(Environment)"
}
Note that stageName is now accessiable - your function could now split on -
, and store the those into variables as required.
To list down other options I tried for reference:
- using different syntaxes to reference variables (macro, template expression, and runtime expression) within the Invoke Azure Function headers, as defined here: https://learn.microsoft/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#understand-variable-syntax
- the only syntax that worked to expand a variable was macro,
$()
- the only syntax that worked to expand a variable was macro,
- moving the stage into a template, parsing a parameter to the template for the stage variables, and attempting to reference the template parameter in the Invoke Azure Function Headers.
- this stack overflow question is similar, but no relevant answer: Access build pipeline output variable in Environment Approval / Check
- this documentation could be helpful, but didn't really clarify why it isn't working in a clear manner (from my understanding): https://learn.microsoft/en-us/azure/devops/pipelines/process/runs?view=azure-devops#pipeline-processing
本文标签: azure devopsEvaluate YAML Stage Variables in Environment Function App GateStack Overflow
版权声明:本文标题:azure devops - Evaluate YAML Stage Variables in Environment Function App Gate - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741894024a2403470.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
AzureFunctions@1
task instead of using it as an environment-defined gate? – Daniel Mann Commented Feb 1 at 7:21Customer
andEnvironment
? Are they defined using macro syntax$(Customer)
for example, or are they hardcoded values as shown in your post-compilation snippet? I'll experiment to find a solution and get back with an answer if I find one over the next couple days. Interesting question! – Scott Richards Commented Feb 1 at 7:28step
where you provide the JSON payload, I can only speculate until that. – GalnaGreta Commented Feb 1 at 9:02