テンプレート使用方法のリファレンス

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

"テンプレート" を使用すると、YAML パイプライン内の再利用可能なコンテンツ、ロジック、およびパラメーターを定義できます。 テンプレートを効果的に操作するには、ステージ、ステップ、ジョブなどの Azure Pipelines の主要な概念を基本的に理解している必要があります。

テンプレートは、開発の高速化に役立ちます。 たとえば、1 つのテンプレートに同じ一連のタスクを含め、YAML パイプラインのさまざまなステージにテンプレートを複数回含めることができます。

テンプレートは、パイプラインをセキュリティで保護するのにも役立ちます。 テンプレートでパイプラインにおいて許可される内容を制御する場合、テンプレートでは別のファイルが従う必要があるロジックを定義します。 たとえば、実行を許可するタスクを制限できます。 そのシナリオでは、テンプレートを使用して、組織のセキュリティ ポリシーに違反するタスクをだれかが正常に実行するのを防ぐことができます。

テンプレートには、インクルードと拡張の 2 種類があります。

  • テンプレートを含め、テンプレートを使用して再利用可能なコンテンツを挿入できます。 テンプレートを使用してコンテンツを含める場合は、多くのプログラミング言語で include ディレクティブのように機能します。 あるファイルのコンテンツが別のファイルに挿入されます。
  • パイプラインで許可される内容をテンプレート コントロールに拡張します。 テンプレートでパイプラインにおいて許可される内容を制御する場合、テンプレートでは別のファイルが従う必要があるロジックを定義します。

テンプレートを最大限に活用するには、テンプレート式テンプレート パラメーターも使用する必要があります。

適用される制限

テンプレートとテンプレート式によって、パイプラインのサイズと複雑さが爆発的に増加する可能性があります。 暴走を防ぐために、Azure Pipelines では次の制限が課されます。

  • (直接または間接的に) 含めることができる YAML ファイル数は 100 個以下です。
  • テンプレートの入れ子 (他のテンプレートを含むテンプレート) は 20 レベル以下です
  • YAML の解析時に使われるメモリは 10 MB 以下です (実際には、使われている特定の機能に応じて、ディスク上の YAML の 600 KB から 2 MB の間が一般的です)

テンプレートを使用してロジックを 1 回定義するだけで、何回も再利用することができます。 テンプレートは、複数の YAML ファイルの内容を 1 つのパイプラインにまとめます。 親パイプラインからテンプレートにパラメーターを渡すことができます。

テンプレートから拡張する

セキュリティを強化するために、特定のテンプレートからパイプラインを拡張するよう強制できます。 ファイル start.yml によって パラメーター buildSteps が定義され、そのパラメーターがパイプライン azure-pipelines.yml で使用されます。 start.yml で、buildStep がスクリプト ステップと共に渡されると拒否され、パイプラインのビルドが失敗します。 テンプレートから拡張する場合は、必要なテンプレート承認を追加することでセキュリティを強化できます。

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

リソースを使用してテンプレートから拡張する

extends を使用して、リソースを含む Azure パイプラインのテンプレートから拡張することもできます。

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

テンプレートを挿入する

1 つの YAML からコンテンツをコピーし、別の YAML で再利用できます。 ある YAML から別の YAML にコンテンツをコピーすると、同じロジックを複数の場所に手動で含める手間を省くことができます。 include-npm-steps.yml ファイル テンプレートには、azure-pipelines.yml で再利用されるステップが含まれています。

注意

テンプレート ファイルは、パイプラインの実行開始時にファイル システムに存在する必要があります。 成果物内のテンプレートを参照することはできません。

# 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

ステップの再利用

テンプレートを挿入することで、複数のジョブで 1 つ以上のステップを再利用できます。 各ジョブでは、テンプレートのステップに加えて、さらにステップを定義できます。

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

ジョブの再利用

ステップと同様に、ジョブもテンプレートで再利用できます。

# 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

複数のジョブを操作する場合は、競合を回避するために、テンプレート ファイル内のジョブの名前を必ず削除してください

# 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

ステージの再利用

ステージもテンプレートで再利用できます。

# 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

パラメーターを含むジョブ、ステージ、ステップのテンプレート

# 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

パイプラインでテンプレートを使用する場合は、テンプレート パラメーターの値を指定します。

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

ステップ テンプレートまたはステージ テンプレートでパラメーターを使用することもできます。 たとえば、パラメーターを含むステップは次のようになります。

# 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

パイプラインでテンプレートを使用する場合は、テンプレート パラメーターの値を指定します。

# File: azure-pipelines.yml

steps:
- script: npm install

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

注意

指定した型を持たないスカラー パラメーターは、文字列として扱われます。 たとえば、eq(true, parameters['myparam']) では、myparam パラメーターが false という単語であっても、myparam が明示的に boolean になっていなければ true を返します。 空でない文字列は、ブール型のコンテキストで true にキャストされます。 そのを書き直して、文字列を明示的に比較できます: eq(parameters['myparam'], 'true')

パラメーターはスカラー文字列に限定されません。 データ型の一覧を参照してください。 たとえば、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 }}

変数の再利用

変数を 1 つの YAML で定義し、別のテンプレートに含めることができます。 これは、すべての変数を 1 つのファイルに格納する場合に便利です。 テンプレートを使用してパイプラインに変数を含める場合、含まれるテンプレートは変数を定義するためにのみ使用できます。 テンプレートから拡張する場合は、ステップとより複雑なロジックを使用できます。 型を制限する場合は、変数の代わりにパラメーターを使用します。

この例では、変数 favoriteVeggieazure-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 }}.

パラメーターを持つ変数テンプレート

テンプレートを使用して変数にパラメーターを渡すことができます。 この例では、DIRECTORY パラメーターを RELEASE_COMMAND 変数に渡しています。

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

パイプラインでテンプレートを使用する場合は、テンプレート パラメーターの値を指定します。

# 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

テンプレート パスを参照する

テンプレート パスには、リポジトリ内の絶対パスを指定することも、インクルードを実行するファイルに対する相対パスを指定することもできます。

絶対パスを使用するには、/ をテンプレート パスの先頭にする必要があります。 他のすべてのパスは相対パスと見なされます。

入れ子になった階層の例を次に示します。

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

次に、以下に示すように fileA.ymlfileB.ymlfileC.yml を参照できます。

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

fileC.yml が始点の場合は、以下に示すように fileA.ymlfileB.yml を含めることができます。

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

fileB.yml が始点の場合は、以下に示すように fileA.ymlfileC.yml を含めることができます。

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

または、このような絶対パスを使用して、fileB.ymlfileA.ymlfileC.yml を参照することもできます。

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

他のリポジトリを使用する

テンプレートは他のリポジトリに保持できます。 たとえば、すべてのアプリ パイプラインで使用するコア パイプラインがあるとします。 テンプレートをコア リポジトリに配置し、各アプリ リポジトリから参照できます。

# 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

これで、このテンプレートを複数のパイプラインで再利用できます。 resources 仕様を使用して、コア リポジトリの場所を指定します。 コア リポジトリを参照する場合は、@ と、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'

type: github の場合は、name は上記の例と同様 <identity>/<repo> です。 type: git (Azure Repos) の場合、name<project>/<repo> です。 そのプロジェクトが別の Azure DevOps 組織にある場合は、プロジェクトへのアクセス権を持つ、Azure Repos/Team Foundation Server 型のサービス接続を構成し、それを YAML に含める必要があります。

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

リポジトリは、パイプラインの起動時に 1 回だけ解決されます。 その後、パイプラインの期間中は同じリソースが使用されます。 使用されるのはテンプレート ファイルのみです。 テンプレートが完全に展開されると、最終的なパイプラインは、ソース リポジトリで完全に定義されているかのように実行されます。 つまり、パイプラインでテンプレート リポジトリのスクリプトを使用することはできません。

特定の固定バージョンのテンプレートを使用する場合は、必ず ref にピン留めしてください。 refs はブランチ (refs/heads/<name>) またはタグ (refs/tags/<name>) のいずれかです。 特定のコミットをピン留めする場合は、まずそのコミットをポイントするタグを作成してから、そのタグにピン留めします。

注意

ref が指定されていない場合、パイプラインは既定で refs/heads/main を使用します。

リポジトリ リソースの SHA 値を使用して、Git の特定のコミットにピン留めすることもできます。 SHA 価値は、コミットを一意に識別する 40 文字のチェックサム ハッシュです。

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

また、@self を使用して、元のパイプラインが見つかったリポジトリを参照することもできます。 これは、extends テンプレートで、拡張パイプラインのリポジトリ内のコンテンツを参照する場合に便利です。 次に例を示します。

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

よく寄せられる質問

テンプレート内で変数を使用するにはどうすればよいですか?

パラメータを変数に基づいた値に設定すると有用な場合があります。 パラメーターはパイプライン実行 の処理の早い段階で展開されるため、すべての変数を使用できるわけではありません。 テンプレートで使用できる定義済み変数を確認するには、「定義済みの変数を使用する」を参照してください。

この例では、定義済みの変数 Build.SourceBranchBuild.Reason が 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