Partilhar via


Use modelos YAML em pipelines para processos reutilizáveis e seguros

Serviços de DevOps do Azure | Azure DevOps Server | Azure DevOps Server 2022

Os modelos permitem definir conteúdo, lógica e parâmetros reutilizáveis em pipelines YAML. Para trabalhar com modelos de forma eficaz, você precisa ter uma compreensão básica de conceitos-chave do Azure Pipelines, como estágios, etapas e trabalhos.

Existem dois tipos principais de modelos:

  • Inclui modelos: Insira conteúdo reutilizável em um pipeline. Se um modelo é usado para incluir conteúdo, ele funciona como uma diretiva include em muitas linguagens de programação. O conteúdo de um modelo é inserido no pipeline ou modelo que o inclui.
  • Estende modelos: Controle e defina um esquema para o que é permitido em um pipeline. Quando um modelo estendido é usado, ele define a lógica e a estrutura que um pipeline deve seguir. Isso é útil para impor padrões de segurança, conformidade ou organizacionais.

Os modelos podem ajudá-lo a acelerar o desenvolvimento. Por exemplo, você pode ter uma série das mesmas tarefas em um modelo e, em seguida, incluir o modelo várias vezes em diferentes estágios do seu pipeline YAML.

Os modelos também podem ajudá-lo a proteger seu pipeline. Quando um modelo controla o que é permitido em um pipeline, o modelo define a lógica que outro arquivo deve seguir. Por exemplo, talvez você queira restringir quais tarefas podem ser executadas. Para esse cenário, você pode usar o modelo para impedir que alguém execute com êxito uma tarefa que viole as políticas de segurança da sua organização.

Para tirar o máximo proveito dos modelos, você também deve usar expressões de modelo e parâmetros de modelo.

Pré-requisitos

Produto Requisitos
Azure DevOps - Um projeto Azure DevOps.
- Capacidade de executar pipelines em agentes hospedados pela Microsoft. Você pode comprar um trabalho paralelo ou solicitar um nível gratuito.
- Conhecimentos básicos de YAML e Azure Pipelines. Para obter mais informações, consulte Criar seu primeiro pipeline.
- Permissões:
     - Para criar um pipeline: você deve estar no grupo Colaboradores e o grupo precisa ter a permissão Criar pipeline de compilação definida como Permitir. Os membros do grupo Administradores de Projeto podem gerenciar pipelines.
    - Para criar conexões de serviço: Você deve ter a função de Administrador ou Criador para conexões de serviço.
GitHub - Uma conta no GitHub .
- Uma conexão de serviço GitHub para autorizar o Azure Pipelines.
Azure Uma assinatura do Azure.

Limites impostos às atualizações de modelos

Os modelos e as expressões de modelos podem causar um crescimento explosivo do tamanho e complexidade de um pipeline. Para ajudar a evitar o crescimento descontrolado, o Azure Pipelines impõe os seguintes limites:

  • Não mais do que 100 arquivos YAML separados podem ser incluídos (direta ou indiretamente)
  • No máximo 100 níveis de aninhamento de modelos (modelos incluindo outros modelos)
  • Não mais do que 20 megabytes de memória consumida durante a análise do YAML (na prática, isso normalmente é entre 600 KB - 2 MB de YAML no disco, dependendo dos recursos específicos usados)

Estender a partir de um modelo

Para aumentar a segurança, você pode impor que um pipeline se estenda a partir de um modelo específico. O arquivo start-extends-template.yml define o parâmetro buildSteps, que é usado no pipeline azure-pipelines.yml. No start-extends-template.yml, se um buildStep for passado com uma etapa de script, ele será rejeitado e a compilação do pipeline falhará. Ao estender a partir de um modelo, você pode aumentar a segurança adicionando uma aprovação de modelo necessária.

# File: start-extends-template.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-extends-template.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"

Estender a partir de um modelo com recursos

Você também pode usar extends para estender a partir de um modelo em seu pipeline do Azure que contém recursos.

# File: azure-pipelines.yml
trigger:
- none

extends:
  template: resource-extends-template.yml
# File: resource-extends-template.yml
resources:
  pipelines:
  - pipeline: my-pipeline 
    source: sourcePipeline

steps:
- script: echo "Testing resource template"

Inserir um modelo

Você pode inserir conteúdo de um YAML e reutilizá-lo em um YAML diferente. Inserir conteúdo de um YAML para outro evita que você tenha que incluir manualmente a mesma lógica em vários lugares. O insert-npm-steps.yml modelo de arquivo contém etapas que são reutilizadas no azure-pipelines.yml.

Nota

Os arquivos de modelo precisam existir em seu sistema de arquivos no início de uma execução de pipeline. Não é possível fazer referência a modelos em um artefato.

# File: templates/insert-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/insert-npm-steps.yml  # Template reference
- job: Windows
  pool:
    vmImage: 'windows-latest'
  steps:
  - template: templates/insert-npm-steps.yml  # Template reference

Reutilizar etapas em várias tarefas

Você pode inserir um modelo para reutilizar uma ou mais etapas em vários trabalhos. Além das etapas do modelo, cada trabalho pode definir mais etapas.

# File: templates/insert-npm-steps.yml
steps:
- script: npm install
- script: npm test
# File: azure-pipelines.yml

jobs:
- job: Linux
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - template: templates/insert-npm-steps.yml  # Template reference

- job: macOS
  pool:
    vmImage: 'macOS-latest'
  steps:
  - template: templates/insert-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/insert-npm-steps.yml  # Template reference
  - script: echo This step runs after the template's steps.

Reutilização de trabalhos em múltiplos modelos

Assim como as etapas, as tarefas podem ser reutilizadas com modelos.

# File: templates/insert-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/insert-jobs.yml  # Template reference

Ao trabalhar com vários trabalhos, lembre-se de remover o nome do trabalho no arquivo de modelo, para evitar conflitos

# File: templates/insert-multiple-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/insert-multiple-job.yml  # Template reference
- template: templates/insert-multiple-jobs.yml  # Template reference
- template: templates/insert-multiple-jobs.yml  # Template reference

Reutilizar estágios em vários modelos

As fases também podem ser reutilizadas com modelos.

# File: templates/insert-stage1.yml
stages:
- stage: Angular
  jobs:
  - job: angularinstall
    steps:
    - script: npm install angular
# File: templates/insert-stage2.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/insert-stage1.yml # Template reference
- template: templates/insert-stage2.yml # Template reference

Adicionar parâmetros a modelos de trabalho, estágio e etapa

Nos seguintes modelos:

  • templates/npm-with-params.yml define dois parâmetros: name e vmImage cria um trabalho com o parâmetro name para o nome do trabalho e o parâmetro vmImage para a imagem VM.
  • O pipeline (azure-pipelines.yml) faz referência ao modelo três vezes, cada uma com valores de parâmetros diferentes referentes ao sistema operacional e aos nomes de imagem da VM.
  • O pipeline criado é executado numa imagem de VM diferente, sendo nomeado segundo o sistema operativo especificado. Cada trabalho executa as etapas de instalação e teste do 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

Ao consumir o modelo no seu pipeline, especifique valores para os parâmetros do modelo.

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

Modelos de palco com vários parâmetros

Nos seguintes modelos:

  • O stage-template.yml modelo define quatro parâmetros: stageName, jobName, vmImage, e scriptPath, todos do tipo string. O modelo cria um palco utilizando o parâmetro stageName para definir o nome, estabelece um trabalho com jobName e inclui uma etapa para executar um script.
  • O pipeline, azure-pipeline.yml, em seguida, define dinamicamente estágios e tarefas usando parâmetros e corre uma tarefa que executa um 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'

Modelos com etapas e parâmetros

Você também pode usar parâmetros com modelos de passo ou fase.

Nos seguintes modelos:

  • O modelo (templates/steps-with-params.yml) define um parâmetro nomeado runExtendedTests com um valor padrão de false.
  • O pipeline (azure-pipelines.yml) funciona npm test e npm test --extended porque o parâmetro runExtendedTests é verdadeiro.
# 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

Ao consumir o modelo em seu pipeline, especifique valores para os parâmetros do modelo.

# File: azure-pipelines.yml

steps:
- script: npm install

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

Nota

Parâmetros escalares sem um tipo especificado são tratados como strings. Por exemplo, eq(true, parameters['myparam']) retornará true, mesmo que o parâmetro myparam seja a palavra false, se myparam não for explicitamente definido como boolean. Strings não vazias são convertidas para true num contexto booleano. Essa expressão poderia ser reescrita para comparar explicitamente cadeias de caracteres: eq(parameters['myparam'], 'true').

Os parâmetros não estão limitados a cadeias escalares. Consulte a lista de tipos de dados. Por exemplo, usando o 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 }}

Reutilização variável

As variáveis podem ser definidas em um YAML e incluídas em outro modelo. Isso pode ser útil se você quiser armazenar todas as suas variáveis em um arquivo. Se você estiver usando um modelo para incluir variáveis em um pipeline, o modelo incluído só poderá ser usado para definir variáveis. Você pode usar etapas e lógica mais complexa quando estiver estendendo a partir de um modelo.

Nota

Use parâmetros em vez de variáveis para maior segurança, como especificar o tipo. Para obter mais informações sobre a importância de usar parâmetros para tarefas de shell, consulte a documentação sobre a validação de argumentos de parâmetros das tarefas de shell Enable.

Neste exemplo, a variável favoriteVeggie está incluída em azure-pipelines.yml.

# File: insert-vars.yml
variables:
  favoriteVeggie: 'brussels sprouts'
# File: azure-pipelines.yml

variables:
- template: insert-vars.yml  # Template reference

steps:
- script: echo My favorite vegetable is ${{ variables.favoriteVeggie }}.

Modelos variáveis com parâmetros

Você pode passar parâmetros para variáveis com modelos. Neste exemplo, você está passando o DIRECTORY parâmetro para uma RELEASE_COMMAND variável.

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

Ao consumir o modelo em seu pipeline, especifique valores para os parâmetros do modelo.

# 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

Estender a partir de um modelo e usar um modelo de inclusão com variáveis

Um cenário comum é ter um pipeline com estágios para desenvolvimento, teste e produção que use um modelo de inclusão de variáveis e um modelo de extensão para estágios e trabalhos.

No exemplo a seguir, variables-template.yml define um conjunto de variáveis de máquina virtual que são usadas no azure-pipeline.yml.

# variables-template.yml

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

O arquivo stage-template.yml a seguir define uma configuração de estágio reutilizável com três parâmetros (name, vmImage, steps) e um trabalho chamado 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 }}

O pipeline a seguir, azure-pipelines.yml, importa variáveis de variables-template.yml e, depois, usa o modelo stage-template.yml para cada estágio. Cada estágio (Dev, Test, Prod) é definido com o mesmo modelo, mas com parâmetros diferentes, levando à consistência entre os estágios, permitindo a personalização. O estágio 'Prod' inclui uma variável de ambiente como exemplo de algo que você pode usar para autenticação. Para saber mais sobre como definir parâmetros, consulte Parâmetros de modelo.

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

Modelos de referência de caminhos

Os caminhos de modelo podem ser um caminho absoluto dentro do repositório ou relativo ao arquivo que faz a inclusão.

Para usar um caminho absoluto, o caminho do modelo deve começar com um /. Todos os outros caminhos são considerados relativos.

Aqui está um exemplo de hierarquia aninhada.

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

Então, em fileA.yml pode referenciar fileB.yml e fileC.yml deste modo.

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

Se fileC.yml for o seu ponto de partida, pode incluir fileA.yml e fileB.yml desta maneira.

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

Quando fileB.yml é o seu ponto de partida, você pode incluir fileA.yml e fileC.yml assim.

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

Alternativamente, fileB.yml poderia referir-se a fileA.yml e fileC.yml usando caminhos absolutos como este.

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

Armazenar modelos em outros repositórios

Você pode manter seus modelos em outros repositórios. Por exemplo, suponha que tenhas um pipeline principal que desejas que todos os pipelines das tuas aplicações utilizem. Você pode colocar o modelo em um repositório principal e, em seguida, consultá-lo a partir de cada um dos repositórios do aplicativo:

# 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

Agora você pode reutilizar esse modelo em vários pipelines. Use a resources especificação para fornecer a localização do repositório principal. Quando se referir ao repositório principal, use @ e o nome que deu a ele em 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'

Para type: github, name é <identity>/<repo> como no exemplo anterior. Para type: git (Azure Repos), name é <project>/<repo>. Se esse projeto estiver em uma organização separada do Azure DevOps, é necessário configurar uma de conexão de serviço do tipo Azure Repos/Team Foundation Server com acesso ao projeto e incluir isso no YAML:

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

Os repositórios são resolvidos apenas uma vez, quando o pipeline inicia. Depois disso, o mesmo recurso é usado durante o processo de execução do pipeline. Somente os arquivos de modelo são usados. Quando os modelos são totalmente expandidos, o pipeline final é executado como se estivesse definido inteiramente no repositório de origem. Isso significa que você não pode usar scripts do repositório de modelos em seu pipeline.

Se quiser usar uma versão específica e fixa do modelo, certifique-se de fixá-la a um ref. As refs são ramificações (refs/heads/<name>) ou tags (refs/tags/<name>). Se você quiser fixar uma confirmação específica, primeiro crie uma tag apontando para essa confirmação e, em seguida, fixe nessa tag.

Nota

Se nenhum ref for especificado, o pipeline assumirá como padrão o uso refs/heads/main.

Você também pode fixar em um commit específico no Git com o valor SHA para um elemento de repositório. O valor SHA é um hash de soma de verificação de 40 caracteres que identifica exclusivamente a confirmação.

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

Você também pode usar @self para fazer referência ao repositório onde o pipeline original foi encontrado. Isso é conveniente para uso em extends templates se você quiser referir-se novamente ao conteúdo no repositório do pipeline que se está a expandir. Por exemplo:

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

FAQ

Como posso utilizar variáveis em modelos?

Há momentos em que é útil definir parâmetros para valores com base em variáveis. Os parâmetros são expandidos no início do processamento de um pipeline, por isso nem todas as variáveis estão disponíveis. Para ver que variáveis predefinidas estão disponíveis nos modelos, veja Utilizar variáveis predefinidas.

Neste exemplo, as variáveis Build.SourceBranch predefinidas e Build.Reason são usadas em condições em 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