I've been trying to implement as per this blog post
I have created a template yaml that received the environment name as a single parameter.
I'd like to call this from a yaml pipeline using stages. Hoping to reduce code duplication, with the idea being the outer calling pipeline yaml is quite simple. This is what I have for the caller:
trigger: none
stages:
- stage: dev
jobs:
- job: dev
extends:
template: templates\365-response.bicep.template.yml
parameters:
env: dev
- stage: test
jobs:
- job: test
extends:
template: templates\365-response.bicep.template.yml
parameters:
env: test
My template to be called is:
name: Deploy Bicep files $(Build.BuildId)
parameters:
- name: env
type: string
variables:
location: "uksouth"
templateFile: "bicep/365Response.main.json"
pool:
vmImage: "windows-latest"
stages:
- stage: preDeploy
jobs:
- job: listFiles
displayName: List Files
pool:
vmImage: windows-2022
steps:
- powershell: echo $(Build.SourcesDirectory)
- powershell: Get-ChildItem -Path '$(System.DefaultWorkingDirectory)' -recurse
- job: scanWhatif
displayName: scan and run whatif
pool:
vmImage: windows-2022
steps:
- task: AzureCLI@2
displayName: Preview Bicep Changes
inputs:
azureSubscription: "subname-${{parameters.env}}"
scriptType: "bash"
scriptLocation: "inlineScript"
inlineScript: |
az --version
az deployment group what-if --resource-group rg-365Response-${{parameters.kbName}}-001 \
--template-file '$(System.DefaultWorkingDirectory)\bicep\365Response.main.bicep' \
--parameters '$(System.DefaultWorkingDirectory)\bicep\365Response.parameters.${{parameters.kbName}}.json' \
- stage: Deploy
displayName: Deploy stage
dependsOn: Build
condition: succeeded()
jobs:
- deployment: Deploy
environment: ${{ parameters.env }}
strategy:
runOnce:
deploy:
steps:
- task: AzureCLI@2
displayName: Deploy Bicep Changes
inputs:
azureSubscription: "subname-${{parameters.env}}"
scriptType: "bash"
scriptLocation: "inlineScript"
inlineScript: |
az deployment group create --resource-group rg-365Response-${{parameters.env}}-001 \
--template-file '$(System.DefaultWorkingDirectory)\bicep\365Response.main.bicep' \
--parameters '$(System.DefaultWorkingDirectory)\bicep\365Response.parameters.${{parameters.env}}.json'
I seem to have the syntax for calling the template wrong?
As per the YAML schema, the extends
keyword applies to pipelines
, not jobs
. The extends keyword is intended as:
# pipeline.yml
trigger:
- main
# these are parameters you show to the user
parameters:
- name: parameter1
type: string
extends:
template: pipeline-template.yml
parameters:
parameter1: ${{ parameters.parameter1 }}
What you trying to do is to create a stage template, but the template you're describing appears to be an entire pipeline.
You'd want your template to look something like this:
# template.yml
parameters:
- name: requiredParameter1
type: string
- name: optionalParameter1
type: string
default: 'default-value'
stages:
- stage: Deploy
jobs:
- job: preDeploy
pool:
vmImage: windows-2022
variables:
myVariable: '${{ parameters.optionalParameter }}'
otherVariable: '${{ parameters.requiredParameter }}'
steps:
...
- job: deploy
steps:
...
And then you'd be able to use it like:
# pipeline.yml
trigger:
- main
stages:
- template: template.yml
parameters:
requiredParameter1: value
A good way to think of templates is like an include file, but it has to adhere to the schema. At compile time it expands the templates into a single file for execution.
A few notes about your current "template":
If you were to remove these elements from your current template, you could use it as a stage template.