I've created a YAML template to extends from with a fixed stage "Deploy" (can not be modified by users, only pass params) and an optional stage "PreDeploy" that should be entirely provided by template users (if they want to add this stage).
parameters:
- name: application
type: string
default: ""
- name: PreDeployStage
type: stage
default:
stage:
jobs:
- job:
stages:
- ${{ parameters.PreDeployStage }}
- stage: 'Deploy'
The pipeline which extends from this template could be something like this:
# azure-pipelines.yml
resources:
repositories:
- repository: temp
type: git
name: templates
ref: refs/heads/main
extends:
template: template.yml@temp
parameters:
Application: APP
PreDeployStage:
stage: Custom
jobs:
- job: StoleSecrets
variables:
- group: Secrets
pool: default
steps:
- task: Whatever task which access to the vars stored in Secrets
There is a variable group called "Secrets" that should never be used in a stage other than "Deploy". In order to prevent template users to provide a stage which uses this variable group (either at stage level or job level) I was wondering if something like this can be used (idea would be to delete all references to "Secrets" variable group in the provided stage).
Is this possible?
EDIT
The workaround proposed by @Alvin Zhao - MSFT gives me a validation error on the steps section:
When trying to save, this is the result:
Seems that the problem is totally focused there because if I replaced the expression with a concrete task, passes validation and works as expected:
The script that currently consumes the template is:
Based on the further disucssions, the pipeline had been passing a whole stage syntax as the value of ${{ parameters.PreDeployStage }}
into the extended template.yml
. Users were able modify the parameter value to be passed in the YAML defintion azure-pipelines.yml
; if with variables: - group: Secrets
added, the pipeline would proceed to reference the variable group Secrets
.
The requirement is to first detect if the parameter value to be passed into template contains such lines to reference variable group Secrets
and then remove to prevent them from passing.
Here are modifed YAML defintion (removing any possibly referenced variables group defined on stage level) and the template for your reference.
azure-pipelines.yml
# azure-pipelines.yml
resources:
repositories:
- repository: temp
type: git
name: templates
ref: refs/heads/main
extends:
template: template.yml@temp
parameters:
Application: APP
PreDeployStage:
stage: Custom
variables:
- group: Secrets # Includes a variable Var1 with the value 1
- group: VG-Y # Includes a variable VarY with the value Y
jobs:
- job: DoNothing
variables:
- group: Secrets
- group: VG-X # Includes a variable VarX with the value X
pool: default
steps:
- script: |
echo Whatever task which access to the vars stored in Secrets variable group
echo "Stage variables defined in parameter $(jsonStageVar)"
echo "Job variables defined in parameters $(jsonJobVar)"
echo "Parameter expects to use Secrets varialbe group? - $(useSecrects)"
echo The value of var1 in group Secrets is "$(Var1)"
echo The value of varX in group VG-X is "$(VarX)"
echo The value of varY in group VG-Y is "$(VarY)"
template.yml
# template.yml
parameters:
- name: application
type: string
default: ""
- name: PreDeployStage
type: stage
default: {}
stages:
- stage: ${{ parameters.PreDeployStage.stage }}
variables:
- name: jsonStageVar
value: ${{ convertToJson(parameters.PreDeployStage.variables) }}
- ${{ each stageVariable in parameters.PreDeployStage.variables }}:
- ${{ if eq(stageVariable.group, 'Secrets') }}:
- name: useSecrects
value: true
- ${{ else }}:
- ${{ stageVariable }}
jobs:
- ${{ each tempJob in parameters.PreDeployStage.jobs}}:
- job: ${{ tempJob.job }}
pool: ${{ tempJob.pool }}
variables:
- name: jsonJobVar
value: ${{ convertToJson(tempJob.variables) }}
- ${{ each jobVariable in tempJob.variables }}:
- ${{ if eq(jobVariable.group, 'Secrets') }}:
- name: useSecrects
value: true
- ${{ else }}:
- ${{ jobVariable }}
steps:
- ${{ tempJob.steps }}
- stage: 'Deploy'
jobs:
- job: JobDeploy
steps:
- script: echo This is Deploy stage
From the expaned YAML defintion in the downloaded logs, we can see the lines - group: secrets
defined in the variables
sections on stage and job levels are replaced.
Please also note that the modified template.yml
splits some but not all properties of the stage and job(s) to be passed in. If other stage/job properties shall be passed, you need to add those mapping properties in temlate.yml
as well; otherwise, they will be ignored during template expansion and will not take effect.