Référence d’utilisation du modèle

Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2019

Les modèles vous permettent de définir du contenu réutilisable, de la logique et des paramètres dans des pipelines YAML. Pour travailler efficacement avec des modèles, vous devez avoir une compréhension de base des concepts clés d’Azure Pipelines, tels que les phases, les étapes et les travaux.

Les modèles peuvent vous aider à accélérer le développement. Par exemple, vous pouvez avoir une série de tâches identiques dans un modèle, puis inclure le modèle plusieurs fois dans différentes étapes de votre pipeline YAML.

Les modèles peuvent également vous aider à sécuriser votre pipeline. Lorsqu’un modèle contrôle ce qui est autorisé dans un pipeline, le modèle définit la logique qu’un autre fichier doit suivre. Par exemple, vous pouvez restreindre les tâches autorisées à s’exécuter. Pour ce scénario, vous pouvez utiliser un modèle pour empêcher une personne d’exécuter correctement une tâche qui enfreint les stratégies de sécurité de votre organisation.

Il existe deux types de modèles : inclut et étend.

  • Inclut des modèles vous permet d’insérer du contenu réutilisable avec un modèle. Si un modèle est utilisé pour inclure du contenu, il fonctionne comme une directive include dans de nombreux langages de programmation. Le contenu d’un fichier est inséré dans un autre fichier.
  • Étend le modèle contrôle ce qui est autorisé dans un pipeline. Lorsqu’un modèle étendu contrôle ce qui est autorisé dans un pipeline, le modèle définit la logique qu’un autre fichier doit suivre.

Pour tirer pleinement parti des modèles, vous devez également utiliser des expressions de modèle et des paramètres de modèle.

Limites imposées

Les modèles et les expressions de modèle peuvent entraîner une croissance explosive de la taille et de la complexité d’un pipeline. Pour éviter une croissance galopante, Azure Pipelines impose les limites suivantes :

  • Pas plus de 100 fichiers YAML distincts peuvent être inclus (directement ou indirectement)
  • Pas plus de 20 niveaux d’imbrication de modèles (modèles incluant d’autres modèles)
  • Pas plus de 10 mégaoctets de mémoire consommés lors de l’analyse du YAML (en pratique, cela représente généralement entre 600 Ko et 2 Mo de YAML sur disque, selon les fonctionnalités spécifiques utilisées)

Utilisez des modèles pour définir votre logique une fois, puis la réutiliser plusieurs fois. Ils combinent le contenu de plusieurs fichiers YAML dans un pipeline unique. Vous pouvez passer des paramètres dans un modèle à partir de votre pipeline parent.

Choisir à partir d'un modèle

Pour renforcer la sécurité, vous pouvez appliquer qu’un pipeline s’étend à partir d’un modèle particulier. Le fichier start.yml définit le paramètre buildSteps, qui est ensuite utilisé dans le pipeline azure-pipelines.yml. Dans start.yml, si un buildStep est passé avec une étape de script, il est rejeté et la build du pipeline échoue. Lors de l’extension à partir d’un modèle, vous pouvez augmenter la sécurité en ajoutant une approbation de modèle requise.

# 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"

Étendre à partir d’un modèle avec des ressources

Vous pouvez également utiliser extends pour étendre à partir d’un modèle dans votre pipeline Azure qui contient des ressources.

# 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"

Insérer un modèle

Vous pouvez copier du contenu à partir d’un YAML et le réutiliser dans un autre YAML. La copie de contenu d’un YAML vers un autre vous évite d’avoir à inclure manuellement la même logique à plusieurs endroits. Le include-npm-steps.yml modèle de fichier contient des étapes qui sont réutilisées dans azure-pipelines.yml.

Notes

Les fichiers de modèle doivent exister sur votre système de fichiers au début de l’exécution d’un pipeline. Vous ne pouvez pas référencer des modèles dans un artefact.

# 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

Réutilisation d’une étape

Vous pouvez insérer un modèle pour réutiliser une ou plusieurs étapes dans plusieurs travaux. En plus des étapes du modèle, chaque travail peut définir d’autres étapes.

# 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.

Réutilisation des travaux

Tout comme les étapes, les travaux peuvent être réutilisés avec des modèles.

# 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

Lorsque vous travaillez avec plusieurs travaux, n’oubliez pas de supprimer le nom du travail dans le fichier de modèle, afin d’éviter les conflits

# 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

Réutilisation de phases

Les phases peuvent également être réutilisées avec des modèles.

# 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

Modèles de travail, de phase et d’étape avec des paramètres

Dans les modèles suivants :

  • templates/npm-with-params.yml définit deux paramètres : name et vmImage et crée une tâche avec le paramètre name pour le nom de la tâche et le paramètre vmImage pour l’image VM.
  • Le pipeline (azure-pipelines.yml) fait référence au modèle trois fois, chacun avec des valeurs de paramètres différentes se référant au système d’exploitation et aux noms d’images VM.
  • Le pipeline construit s’exécute sur une image VM différente et est nommé en fonction du système d’exploitation spécifié. Chaque tâche exécute les étapes npm install et npm test.
# 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

Lorsque vous utilisez le modèle dans votre pipeline, spécifiez des valeurs pour les paramètres du modèle.

# 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'

Modèles de stage avec plusieurs paramètres

Dans les modèles suivants :

  • Le modèle stage-template.yml définit quatre paramètres : stageName, jobName, vmImage, et scriptPath, tous de type string. Le modèle crée un stage en utilisant le paramètre stageName pour définir le nom du stage, définit une tâche avec jobName et inclut une étape pour exécuter un script.
  • Le pipeline, azure-pipeline.yml, définit ensuite dynamiquement des stages et des tâches en utilisant des paramètres et exécute une tâche qui exécute un 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'

Modèles avec des étapes et des paramètres

Vous pouvez également utiliser des paramètres avec des modèles d’étape ou de phase.

Dans les modèles suivants :

  • Le modèle (templates/steps-with-params.yml) définit un paramètre nommé runExtendedTests avec une valeur par défaut de false.
  • Le pipeline (azure-pipelines.yml) exécute npm test et npm test --extended parce que le paramètre runExtendedTests est vrai.
# 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

Lorsque vous utilisez le modèle dans votre pipeline, spécifiez des valeurs pour les paramètres du modèle.

# File: azure-pipelines.yml

steps:
- script: npm install

- template: templates/steps-with-params.yml  # Template reference
  parameters:
    runExtendedTests: 'true'

Notes

Les paramètres scalaires sans type spécifié sont traités comme des chaînes. Par exemple, eq(true, parameters['myparam']) retourne true, même si le myparam paramètre est le mot false, si myparam n’est pas explicitement créé boolean. Les chaînes non vides sont converties en true dans un contexte booléen. Cette expression peut être réécrite pour comparer explicitement les chaînes : eq(parameters['myparam'], 'true').

Les paramètres ne sont pas limités aux chaînes scalaires. Consultez la liste des types de données. Par exemple, à l’aide du type object :

# 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 }}

Réutilisation des variables

Les variables peuvent être définies dans un YAML et incluses dans un autre modèle. Cela peut être utile si vous souhaitez stocker toutes vos variables dans un seul fichier. Si vous utilisez un modèle pour inclure des variables dans un pipeline, le modèle inclus ne peut être utilisé que pour définir des variables. Vous pouvez utiliser des étapes et une logique plus complexe lorsque vous étendez à partir d’un modèle. Utilisez des paramètres au lieu de variables lorsque vous souhaitez restreindre le type.

Dans cet exemple, la variable favoriteVeggie est incluse dans 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 }}.

Modèles de variables avec paramètres

Vous pouvez passer des paramètres à des variables avec des modèles. Dans cet exemple, vous transmettez le DIRECTORY paramètre à une RELEASE_COMMAND variable.

# 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}'  

Lorsque vous utilisez le modèle dans votre pipeline, spécifiez des valeurs pour les paramètres du modèle.

# 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

Étendre à partir d’un modèle et utiliser un modèle d’inclusion avec des variables

Un scénario courant consiste à avoir un pipeline avec des étapes pour le développement, les tests et la production qui utilise à la fois un modèle pour les variables et un modèle d'extension pour les étapes ou les travaux.

Dans l'exemple suivant, variables-template.yml définit un ensemble de variables de machine virtuelle qui sont ensuite utilisées dans azure-pipeline.yml.

# variables-template.yml

variables:
- name: devVmImage
  value: 'ubuntu-latest'
- name: testVmImage
  value: 'ubuntu-latest'
- name: prodVmImage
  value: 'ubuntu-latest'

Le fichier suivant, stage-template.yml, définit une configuration d'étape réutilisable avec trois paramètres (name, vmImage, steps) et un travail nommé 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 }}

Le pipeline suivant, azure-pipelines.yml, importe des variables de variables-template.yml, puis utilise le modèle stage-template.yml pour chaque étape. Chaque étape (Dev, Test, Prod) est définie avec le même modèle mais avec des paramètres différents, ce qui permet d'obtenir une cohérence entre les étapes tout en permettant une personnalisation. L’étape Prod inclut une variable d’environnement comme exemple de quelque chose que vous pouvez utiliser pour l’authentification.

# 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)

Chemins d’accès au modèle de référence

Les chemins d’accès au modèle peuvent être un chemin d’accès absolu dans le référentiel ou par rapport au fichier qui effectue l’inclusion.

Pour utiliser un chemin d’accès absolu, le chemin d’accès au modèle doit commencer par un /. Tous les autres chemins d’accès sont considérés comme relatifs.

Voici un exemple de hiérarchie imbriquée.

|
+-- fileA.yml
|
+-- dir1/
     |
     +-- fileB.yml
     |
     +-- dir2/
          |
          +-- fileC.yml

Ensuite, dans fileA.yml vous pouvez référencer fileB.yml et fileC.yml comme ceci.

steps:
- template: dir1/fileB.yml
- template: dir1/dir2/fileC.yml

Si fileC.yml est votre point de départ, vous pouvez inclure fileA.yml et fileB.yml comme ceci.

steps:
- template: ../../fileA.yml
- template: ../fileB.yml

Quand fileB.yml est votre point de départ, vous pouvez inclure fileA.yml et fileC.yml comme ceci.

steps:
- template: ../fileA.yml
- template: dir2/fileC.yml

fileB.yml peut également faire référence à fileA.yml et à fileC.yml en utilisant des chemins d’accès absolus comme celui-ci.

steps:
- template: /fileA.yml
- template: /dir1/dir2/fileC.yml

Utiliser d’autres référentiels

Vous pouvez conserver vos modèles dans d’autres référentiels. Par exemple, supposons que vous ayez un pipeline principal que vous souhaitez que tous vos pipelines d’application utilisent. Vous pouvez placer le modèle dans un référentiel principal, puis y faire référence à partir de chacun de vos référentiels d’application :

# 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

Vous pouvez maintenant réutiliser ce modèle dans plusieurs pipelines. Utilisez la resources spécification pour fournir l’emplacement du référentiel principal. Lorsque vous faites référence au référentiel principal, utilisez @ et le nom que vous lui avez donné dans 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'

Pour type: github, name est <identity>/<repo> comme dans les exemples ci-dessus. Pour type: git (Azure Repos), name est <project>/<repo>. Si ce projet se trouve dans un organisation Azure DevOps distinct, vous devez configurer une connexion de service de type Azure Repos/Team Foundation Server avec accès au projet et l’inclure dans YAML :

resources:
  repositories:
  - repository: templates
    name: Contoso/BuildTemplates
    endpoint: myServiceConnection # Azure DevOps service connection
jobs:
- template: common.yml@templates

Les référentiels ne sont résolus qu’une seule fois, au démarrage du pipeline. Après cela, la même ressource est utilisée pendant la durée du pipeline. Seuls les fichiers de modèle sont utilisés. Une fois les modèles entièrement développés, le pipeline final s’exécute comme s’il était entièrement défini dans le référentiel source. Cela signifie que vous ne pouvez pas utiliser les scripts du référentiel de modèles dans votre pipeline.

Si vous souhaitez utiliser une version particulière et fixe du modèle, veillez à épingler à un ref. Les refs sont des branches (refs/heads/<name>) ou des balises (refs/tags/<name>). Si vous souhaitez épingler un commit spécifique, créez d’abord une balise pointant vers cette validation, puis épinglez-la à cette balise.

Notes

Si aucun ref n’est spécifié, le pipeline utilise refs/heads/mainpar défaut .

Vous pouvez également épingler à une validation spécifique dans Git avec la valeur SHA d’une ressource de référentiel. La valeur SHA est un code de hachage de somme de contrôle de 40 caractères qui identifie seulement le commit.

resources:
  repositories:
    - repository: templates
      type: git
      name: Contoso/BuildTemplates
      ref: 1234567890abcdef1234567890abcdef12345678

Vous pouvez également utiliser @self pour faire référence au référentiel où le pipeline d’origine a été trouvé. Cela est pratique pour une utilisation dans extends les modèles si vous souhaitez faire référence au contenu dans le référentiel du pipeline d’extension. Par exemple :

# 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: []

Forum aux questions

Comment utiliser des variables à l’intérieur des modèles ?

Il peut parfois être utile de définir des paramètres sur des valeurs basées sur des variables. Les paramètres étant développés au début du traitement d’une exécution de pipeline, toutes les variables ne sont donc pas disponibles. Pour voir quelles variables prédéfinies sont disponibles dans des modèles, consultez Utiliser des variables prédéfinies.

Dans cet exemple, les variables Build.SourceBranch prédéfinies et Build.Reason sont utilisées dans des conditions dans 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