Informazioni di riferimento sull'utilizzo dei modelli
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
I modelli consentono di definire contenuto riutilizzabile, logica e parametri nelle pipeline YAML. Per usare i modelli in modo efficace, è necessario avere una conoscenza di base dei concetti chiave di Azure Pipelines, ad esempio fasi, passaggi e processi.
I modelli consentono di velocizzare lo sviluppo. Ad esempio, è possibile avere una serie di stesse attività in un modello e quindi includere il modello più volte in diverse fasi della pipeline YAML.
I modelli consentono anche di proteggere la pipeline. Quando un modello controlla ciò che è consentito in una pipeline, il modello definisce la logica che deve essere seguita da un altro file. Ad esempio, è possibile limitare le attività consentite per l'esecuzione. Per questo scenario, è possibile usare un modello per impedire a un utente di eseguire correttamente un'attività che viola i criteri di sicurezza dell'organizzazione.
Esistono due tipi di modelli: include ed estende.
- Include modelli che consentono di inserire contenuto riutilizzabile con un modello. Se un modello viene usato per includere contenuto, funziona come una direttiva di inclusione in molti linguaggi di programmazione. Il contenuto di un file viene inserito in un altro file.
- Estende il controllo modello che cosa è consentito in una pipeline. Quando un modello estende controlla ciò che è consentito in una pipeline, il modello definisce la logica che deve essere seguita da un altro file.
Per sfruttare appieno i vantaggi dei modelli, è consigliabile usare anche espressioni di modello e parametri di modello.
Limiti imposti
I modelli e le espressioni di modello possono causare una crescita esponenziale delle dimensioni e della complessità di una pipeline. Per evitare la crescita in fuga, Azure Pipelines impone i limiti seguenti:
- Non è possibile includere più di 100 file YAML separati (direttamente o indirettamente)
- Non è possibile avere più di 20 livelli di annidamento dei modelli (modelli che includono altri modelli)
- Non più di 10 megabyte di memoria utilizzata durante l'analisi di YAML (in pratica, questo è in genere compreso tra 600 KB - 2 MB di YAML su disco, a seconda delle funzionalità specifiche usate)
Usare i modelli per definire la logica una sola volta e quindi riutilizzarla più volte. I modelli combinano il contenuto di più file YAML in una singola pipeline. È possibile passare parametri in un modello dalla pipeline padre.
Estendere da un modello
Per aumentare la sicurezza, è possibile imporre che una pipeline si estenda da un modello specifico. Il file start.yml
definisce il parametro buildSteps
, che viene quindi usato nella pipeline azure-pipelines.yml
.
In start.yml
, se un buildStep
oggetto viene passato con un passaggio di script, viene rifiutato e la compilazione della pipeline ha esito negativo.
Quando si estende da un modello, è possibile aumentare la sicurezza aggiungendo un'approvazione del modello richiesta.
# File: start.yml
parameters:
- name: buildSteps # the name of the parameter is buildSteps
type: stepList # data type is StepList
default: [] # default value of buildSteps
stages:
- stage: secure_buildstage
pool:
vmImage: windows-latest
jobs:
- job: secure_buildjob
steps:
- script: echo This happens before code
displayName: 'Base: Pre-build'
- script: echo Building
displayName: 'Base: Build'
- ${{ each step in parameters.buildSteps }}:
- ${{ each pair in step }}:
${{ if ne(pair.value, 'CmdLine@2') }}:
${{ pair.key }}: ${{ pair.value }}
${{ if eq(pair.value, 'CmdLine@2') }}:
# Step is rejected by raising a YAML syntax error: Unexpected value 'CmdLine@2'
'${{ pair.value }}': error
- script: echo This happens after code
displayName: 'Base: Signing'
# File: azure-pipelines.yml
trigger:
- main
extends:
template: start.yml
parameters:
buildSteps:
- bash: echo Test #Passes
displayName: succeed
- bash: echo "Test"
displayName: succeed
# Step is rejected by raising a YAML syntax error: Unexpected value 'CmdLine@2'
- task: CmdLine@2
inputs:
script: echo "Script Test"
# Step is rejected by raising a YAML syntax error: Unexpected value 'CmdLine@2'
- script: echo "Script Test"
Estendere da un modello con risorse
È anche possibile usare extends
per estendere da un modello nella pipeline di Azure che contiene risorse.
# File: azure-pipelines.yml
trigger:
- none
extends:
template: resource-template.yml
# File: resource-template.yml
resources:
pipelines:
- pipeline: my-pipeline
source: sourcePipeline
steps:
- script: echo "Testing resource template"
Inserire un modello
È possibile copiare il contenuto da un FILE YAML e riutilizzarlo in un YAML diverso. La copia del contenuto da un YAML a un'altra consente di evitare di dover includere manualmente la stessa logica in più posizioni. Il include-npm-steps.yml
modello di file contiene i passaggi riutilizzati in azure-pipelines.yml
.
Nota
I file modello devono esistere nel file system all'inizio di un'esecuzione della pipeline. Non è possibile fare riferimento ai modelli in un artefatto.
# File: templates/include-npm-steps.yml
steps:
- script: npm install
- script: yarn install
- script: npm run compile
# File: azure-pipelines.yml
jobs:
- job: Linux
pool:
vmImage: 'ubuntu-latest'
steps:
- template: templates/include-npm-steps.yml # Template reference
- job: Windows
pool:
vmImage: 'windows-latest'
steps:
- template: templates/include-npm-steps.yml # Template reference
Riutilizzo dei passaggi
È possibile inserire un modello per riutilizzare uno o più passaggi tra diversi processi. Oltre ai passaggi del modello, ogni processo può definire altri passaggi.
# File: templates/npm-steps.yml
steps:
- script: npm install
- script: npm test
# File: azure-pipelines.yml
jobs:
- job: Linux
pool:
vmImage: 'ubuntu-latest'
steps:
- template: templates/npm-steps.yml # Template reference
- job: macOS
pool:
vmImage: 'macOS-latest'
steps:
- template: templates/npm-steps.yml # Template reference
- job: Windows
pool:
vmImage: 'windows-latest'
steps:
- script: echo This script runs before the template's steps, only on Windows.
- template: templates/npm-steps.yml # Template reference
- script: echo This step runs after the template's steps.
Riutilizzo del processo
Analogamente ai passaggi, i processi possono essere riutilizzati con i modelli.
# File: templates/jobs.yml
jobs:
- job: Ubuntu
pool:
vmImage: 'ubuntu-latest'
steps:
- bash: echo "Hello Ubuntu"
- job: Windows
pool:
vmImage: 'windows-latest'
steps:
- bash: echo "Hello Windows"
# File: azure-pipelines.yml
jobs:
- template: templates/jobs.yml # Template reference
Quando si usano più processi, ricordarsi di rimuovere il nome del processo nel file modello, in modo da evitare conflitti
# File: templates/jobs.yml
jobs:
- job:
pool:
vmImage: 'ubuntu-latest'
steps:
- bash: echo "Hello Ubuntu"
- job:
pool:
vmImage: 'windows-latest'
steps:
- bash: echo "Hello Windows"
# File: azure-pipelines.yml
jobs:
- template: templates/jobs.yml # Template reference
- template: templates/jobs.yml # Template reference
- template: templates/jobs.yml # Template reference
Riutilizzo della fase
Le fasi possono anche essere riutilizzate con i modelli.
# File: templates/stages1.yml
stages:
- stage: Angular
jobs:
- job: angularinstall
steps:
- script: npm install angular
# File: templates/stages2.yml
stages:
- stage: Build
jobs:
- job: build
steps:
- script: npm run build
# File: azure-pipelines.yml
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: Install
jobs:
- job: npminstall
steps:
- task: Npm@1
inputs:
command: 'install'
- template: templates/stages1.yml # Template reference
- template: templates/stages2.yml # Template reference
Modelli di processo, fase e passaggio con parametri
Nei modelli seguenti:
templates/npm-with-params.yml
definisce due parametri:name
e evmImage
crea un processo con il parametro name per il nome del processo e il parametro vmImage per l'immagine della macchina virtuale.- La pipeline (
azure-pipelines.yml
) fa riferimento al modello tre volte, ognuno con valori di parametro diversi che fanno riferimento ai nomi del sistema operativo e delle immagini della macchina virtuale. - La pipeline compilata viene eseguita in un'immagine di macchina virtuale diversa e denominata in base al sistema operativo specificato. Ogni processo esegue i passaggi di test npm install e npm.
# File: templates/npm-with-params.yml
parameters:
- name: name # defaults for any parameters that aren't specified
default: ''
- name: vmImage
default: ''
jobs:
- job: ${{ parameters.name }}
pool:
vmImage: ${{ parameters.vmImage }}
steps:
- script: npm install
- script: npm test
Quando si utilizza il modello nella pipeline, specificare i valori per i parametri del modello.
# File: azure-pipelines.yml
jobs:
- template: templates/npm-with-params.yml # Template reference
parameters:
name: Linux
vmImage: 'ubuntu-latest'
- template: templates/npm-with-params.yml # Template reference
parameters:
name: macOS
vmImage: 'macOS-latest'
- template: templates/npm-with-params.yml # Template reference
parameters:
name: Windows
vmImage: 'windows-latest'
Preparare i modelli con più parametri
Nei modelli seguenti:
- Il
stage-template.yml
modello definisce quattro parametri:stageName
,jobName
,vmImage
escriptPath
, tutti di tipo string. Il modello crea una fase usando il parametro per impostare ilstageName
nome della fase, definisce un processo conjobName
e include un passaggio per eseguire uno script. - La pipeline,
azure-pipeline.yml
, quindi definisce dinamicamente fasi e processi usando i parametri ed esegue un processo che esegue uno script,build-script.sh
.
# stage-template.yml
parameters:
- name: stageName
type: string
- name: jobName
type: string
- name: vmImage
type: string
- name: scriptPath
type: string
stages:
- stage: ${{ parameters.stageName }}
jobs:
- job: ${{ parameters.jobName }}
pool:
vmImage: ${{ parameters.vmImage }}
steps:
- script: ./${{ parameters.scriptPath }}
# azure-pipelines.yml
trigger:
- main
stages:
- template: stage-template.yml
parameters:
stageName: 'BuildStage'
jobName: 'BuildJob'
scriptPath: 'build-script.sh' # replace with script in your repository
vmImage: 'ubuntu-latest'
Modelli con passaggi e parametri
È anche possibile usare i parametri con modelli di passaggio o di fase.
Nei modelli seguenti:
- Il modello (
templates/steps-with-params.yml
) definisce un parametro denominatorunExtendedTests
con un valore predefinito false. - La pipeline (
azure-pipelines.yml
) viene eseguitanpm test
enpm test --extended
perché ilrunExtendedTests
parametro è true.
# File: templates/steps-with-params.yml
parameters:
- name: 'runExtendedTests' # defaults for any parameters that aren't specified
type: boolean
default: false
steps:
- script: npm test
- ${{ if eq(parameters.runExtendedTests, true) }}:
- script: npm test --extended
Quando si utilizza il modello nella pipeline, specificare i valori per i parametri del modello.
# File: azure-pipelines.yml
steps:
- script: npm install
- template: templates/steps-with-params.yml # Template reference
parameters:
runExtendedTests: 'true'
Nota
I parametri scalari senza un tipo specificato vengono considerati come stringhe.
Ad esempio, eq(true, parameters['myparam'])
restituirà true
, anche se il myparam
parametro è la parola false
, se myparam
non viene esplicitamente reso boolean
.
Le stringhe non vuote vengono cast in true
in un contesto booleano.
Tale espressione può essere riscritta per confrontare in modo esplicito le stringhe: eq(parameters['myparam'], 'true')
.
I parametri non sono limitati alle stringhe scalari.
Vedere l'elenco dei tipi di dati.
Ad esempio, usando il object
tipo :
# azure-pipelines.yml
jobs:
- template: process.yml
parameters:
pool: # this parameter is called `pool`
vmImage: ubuntu-latest # and it's a mapping rather than a string
# process.yml
parameters:
- name: 'pool'
type: object
default: {}
jobs:
- job: build
pool: ${{ parameters.pool }}
Riutilizzo delle variabili
Le variabili possono essere definite in un file YAML e incluse in un altro modello. Questo può essere utile se si desidera archiviare tutte le variabili in un unico file. Se si usa un modello per includere variabili in una pipeline, il modello incluso può essere usato solo per definire le variabili. È possibile usare i passaggi e la logica più complessa quando si esegue l'estensione da un modello. Usare i parametri anziché le variabili quando si vuole limitare il tipo.
In questo esempio la variabile favoriteVeggie
è inclusa in azure-pipelines.yml
.
# File: vars.yml
variables:
favoriteVeggie: 'brussels sprouts'
# File: azure-pipelines.yml
variables:
- template: vars.yml # Template reference
steps:
- script: echo My favorite vegetable is ${{ variables.favoriteVeggie }}.
Modelli di variabile con parametro
È possibile passare parametri alle variabili con i modelli. In questo esempio si passa il DIRECTORY
parametro a una RELEASE_COMMAND
variabile.
# File: templates/package-release-with-params.yml
parameters:
- name: DIRECTORY
type: string
default: "." # defaults for any parameters that specified with "." (current directory)
variables:
- name: RELEASE_COMMAND
value: grep version ${{ parameters.DIRECTORY }}/package.json | awk -F \" '{print $4}'
Quando si utilizza il modello nella pipeline, specificare i valori per i parametri del modello.
# File: azure-pipelines.yml
variables: # Global variables
- template: package-release-with-params.yml # Template reference
parameters:
DIRECTORY: "azure/checker"
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: Release_Stage
displayName: Release Version
variables: # Stage variables
- template: package-release-with-params.yml # Template reference
parameters:
DIRECTORY: "azure/todo-list"
jobs:
- job: A
steps:
- bash: $(RELEASE_COMMAND) #output release command
Estendere da un modello e usare un modello di inclusione con variabili
Uno scenario comune consiste nell'avere una pipeline con fasi per lo sviluppo, il test e la produzione che usa sia un modello per le variabili che un modello estende per fasi o processi.
Nell'esempio seguente viene variables-template.yml
definito un set di variabili di macchina virtuale che vengono quindi usate in azure-pipeline.yml
.
# variables-template.yml
variables:
- name: devVmImage
value: 'ubuntu-latest'
- name: testVmImage
value: 'ubuntu-latest'
- name: prodVmImage
value: 'ubuntu-latest'
Il file seguente definisce stage-template.yml
una configurazione di fase riutilizzabile con tre parametri (name
, vmImage
, steps
) e un processo denominato Build
.
# stage-template.yml
parameters:
- name: name
type: string
default: ''
- name: vmImage
type: string
default: ''
- name: steps
type: stepList
default: []
stages:
- stage: ${{ parameters.name }}
jobs:
- job: Build
pool:
vmImage: ${{ parameters.vmImage }}
steps: ${{ parameters.steps }}
La pipeline seguente, azure-pipelines.yml
, importa le variabili da variables-template.yml
e quindi usa il stage-template.yml
modello per ogni fase. Ogni fase (Sviluppo, Test, Prod) viene definita con lo stesso modello, ma con parametri diversi, portando alla coerenza tra le fasi, consentendo al tempo stesso la personalizzazione. La fase Prod include una variabile di ambiente come esempio di un elemento che è possibile usare per l'autenticazione.
# azure-pipelines.yml
trigger:
- main
variables:
- template: variables-template.yml
stages:
- template: stage-template.yml
parameters:
name: Dev
vmImage: ${{ variables.devVmImage }}
steps:
- script: echo "Building in Dev"
- template: stage-template.yml
parameters:
name: Test
vmImage: ${{ variables.testVmImage }}
steps:
- script: echo "Testing in Test"
- template: stage-template.yml
parameters:
name: Prod
vmImage: ${{ variables.prodVmImage }}
steps:
- script: echo "Deploying to Prod"
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
Percorsi dei modelli di riferimento
I percorsi dei modelli possono essere un percorso assoluto all'interno del repository o rispetto al file che esegue l'inclusione.
Per usare un percorso assoluto, il percorso del modello deve iniziare con ./
Tutti gli altri percorsi vengono considerati relativi.
Ecco un esempio di gerarchia annidata.
|
+-- fileA.yml
|
+-- dir1/
|
+-- fileB.yml
|
+-- dir2/
|
+-- fileC.yml
Quindi, in fileA.yml
è possibile fare riferimento fileB.yml
e fileC.yml
in questo modo.
steps:
- template: dir1/fileB.yml
- template: dir1/dir2/fileC.yml
Se fileC.yml
è il punto di partenza, è possibile includere fileA.yml
e fileB.yml
in questo modo.
steps:
- template: ../../fileA.yml
- template: ../fileB.yml
Quando fileB.yml
è il punto di partenza, è possibile includere fileA.yml
e fileC.yml
in questo modo.
steps:
- template: ../fileA.yml
- template: dir2/fileC.yml
In alternativa, fileB.yml
potrebbe fare riferimento a fileA.yml
e fileC.yml
usare percorsi assoluti come questo.
steps:
- template: /fileA.yml
- template: /dir1/dir2/fileC.yml
Uso di altri repository
È possibile mantenere i modelli in altri repository. Si supponga, ad esempio, di avere una pipeline di base che si vuole usare tutte le pipeline dell'app. È possibile inserire il modello in un repository principale e quindi farvi riferimento da ogni repository dell'app:
# Repo: Contoso/BuildTemplates
# File: common.yml
parameters:
- name: 'vmImage'
default: 'ubuntu-22.04'
type: string
jobs:
- job: Build
pool:
vmImage: ${{ parameters.vmImage }}
steps:
- script: npm install
- script: npm test
È ora possibile riutilizzare questo modello in più pipeline.
Usare la resources
specifica per specificare la posizione del repository principale.
Quando si fa riferimento al repository principale, usare @
e il nome assegnato in resources
.
# Repo: Contoso/LinuxProduct
# File: azure-pipelines.yml
resources:
repositories:
- repository: templates
type: github
name: Contoso/BuildTemplates
jobs:
- template: common.yml@templates # Template reference
# Repo: Contoso/WindowsProduct
# File: azure-pipelines.yml
resources:
repositories:
- repository: templates
type: github
name: Contoso/BuildTemplates
ref: refs/tags/v1.0 # optional ref to pin to
jobs:
- template: common.yml@templates # Template reference
parameters:
vmImage: 'windows-latest'
Per type: github
, name
è <identity>/<repo>
come negli esempi precedenti.
Per type: git
(Azure Repos), name
è <project>/<repo>
.
Se il progetto si trova in un'organizzazione Azure DevOps separata, è necessario configurare una connessione al servizio di tipo Azure Repos/Team Foundation Server
con accesso al progetto e includerla in YAML:
resources:
repositories:
- repository: templates
name: Contoso/BuildTemplates
endpoint: myServiceConnection # Azure DevOps service connection
jobs:
- template: common.yml@templates
I repository vengono risolti una sola volta, all'avvio della pipeline. Successivamente, la stessa risorsa viene usata per la durata della pipeline. Vengono usati solo i file modello. Una volta espansi completamente i modelli, la pipeline finale viene eseguita come se fosse stata definita interamente nel repository di origine. Ciò significa che non è possibile usare script dal repository del modello nella pipeline.
Se si vuole usare una particolare versione fissa del modello, assicurarsi di aggiungere a un oggetto ref
.
refs
sono rami (refs/heads/<name>
) o tag (refs/tags/<name>
).
Se si vuole aggiungere un commit specifico, creare prima di tutto un tag che punta a tale commit, quindi aggiungere a tale tag.
Nota
Se non viene specificato alcun ref
valore, per impostazione predefinita la pipeline usa refs/heads/main
.
È anche possibile aggiungere a un commit specifico in Git con il valore SHA per una risorsa del repository. Il valore SHA è un hash checksum di 40 caratteri che identifica in modo univoco il commit.
resources:
repositories:
- repository: templates
type: git
name: Contoso/BuildTemplates
ref: 1234567890abcdef1234567890abcdef12345678
È anche possibile usare @self
per fare riferimento al repository in cui è stata trovata la pipeline originale.
Ciò è utile per l'uso nei extends
modelli se si vuole fare riferimento al contenuto nel repository della pipeline di estensione.
Ad esempio:
# Repo: Contoso/Central
# File: template.yml
jobs:
- job: PreBuild
steps: []
# Template reference to the repo where this template was
# included from - consumers of the template are expected
# to provide a "BuildJobs.yml"
- template: BuildJobs.yml@self
- job: PostBuild
steps: []
# Repo: Contoso/MyProduct
# File: azure-pipelines.yml
resources:
repositories:
- repository: templates
type: git
name: Contoso/Central
extends:
template: template.yml@templates
# Repo: Contoso/MyProduct
# File: BuildJobs.yml
jobs:
- job: Build
steps: []
Domande frequenti
Come usare le variabili all'interno dei modelli?
In alcuni casi può essere utile impostare i parametri sui valori in base alle variabili. I parametri vengono espansi all'inizio dell'elaborazione di una pipeline in modo che non tutte le variabili siano disponibili. Per informazioni sulle variabili predefinite disponibili nei modelli, vedere Usare variabili predefinite.
In questo esempio le variabili Build.SourceBranch
predefinite e Build.Reason
vengono usate in condizioni in template.yml.
# File: azure-pipelines.yml
trigger:
- main
extends:
template: template.yml
# File: template.yml
steps:
- script: echo Build.SourceBranch = $(Build.SourceBranch) # outputs refs/heads/main
- script: echo Build.Reason = $(Build.Reason) # outputs IndividualCI
- ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
- script: echo I run only if Build.SourceBranch = refs/heads/main
- ${{ if eq(variables['Build.Reason'], 'IndividualCI') }}:
- script: echo I run only if Build.Reason = IndividualCI
- script: echo I run after the conditions