🐧

Azure Pipelinesを活用したマルチテナント環境へのDockerイメージPush

2024/09/15に公開

1. はじめに

Azure Pipelinesを使用して、DockerイメージをAzure Container Registry (ACR) にPushする際、通常はAzure DevOpsと同じテナントのACRに接続するため、Docker Registryタイプのサービスコネクションを利用することで簡単に設定が可能です。しかし、異なるテナントのACRにPushする場合、Azure Resource Managerタイプのサービスコネクションを手動で作成し、Azureポータルでサービスプリンシパルを作成して適切な権限を付与する必要があります。本記事では、同じテナントおよび異なるテナントに対するACRへのPush手順をそれぞれ解説します。

本記事のソースコードは、Gitに登録しています。

https://github.com/yutaka-art/azure-pipelines-multi-tenant-acr-push

2. 同じテナントの場合

Azure DevOpsと同じテナントのACRに対しては、Docker Registryタイプのサービスコネクションを使うことができます。この場合、Docker@2タスクを使用してイメージのビルドとPushが可能です。

2.1 サンプル YAML

trigger:
  branches:
    include:
    - main
  paths:
    include:
    - src/*

variables:
  serviceConnectionName: '<your service connection>'
  containerRegistoryName: '<your acr name>'
  containerImageName: '<your acr image name>'
  containerImageTag: '<your acr image tag name>'

stages:
  # Publish
  - stage: DockerBuildAndPush
    displayName: 'Build and Push Docker Image'
    jobs:
    - job: BuildAndPushImage
      displayName: 'Build and Push Docker Image Job'
      pool:
        vmImage: 'ubuntu-latest'
      steps:
        - task: Docker@2
          displayName: 'Build and Push Docker image'
          inputs:
            command: buildAndPush
            repository: $(containerImageName)
            dockerfile: '$(Build.SourcesDirectory)/src/Dockerfile'
            containerRegistry: $(serviceConnectionName)
            tags: |
              $(containerImageTag)

説明

このYAMLスクリプトでは、Docker@2タスクを使用してDockerイメージをビルドし、同じテナント内のACRにPushします。serviceConnectionNameには、事前に作成したDocker Registryタイプのサービスコネクションを指定します。

3. 異なるテナントの場合

異なるテナントのACRに対しては、Azure Resource Managerタイプのサービスコネクションを手動で作成する必要があります。自動で作成することはできず、Azure側でサービスプリンシパルを作成し、Azure DevOpsにてそのサービスプリンシパルを利用する設定が必要です。

3.1 サービスプリンシパルの作成手順

  1. Azureポータルにてサービスプリンシパルを作成。
    Azure Portal から Entra ID を選択し、アプリの登録をします。

+新規登録 をクリックし、任意の名前を入力し、登録をクリックします。

アプリが作成されるので、表示されている、アプリケーション (クライアント) IDディレクトリ (テナント) IDをメモしておきましょう。※あとからAzure DevOpsのサービスコネクションを登録する際に利用します。
続いて、証明書とシークレットをクリックします。

+新しいクライアント シークレットをクリックします。

説明と、有効期限を設定し、追加をクリックします。

シークレット値をメモしておきましょう。この値は閉じると二度と表示されませんが、忘れてしまっても異なる値となりますが再度作り出すことができます。

  1. サービスプリンシパルに必要な権限(ACRへのアクセス権など)を割り当てる。

  2. Azure DevOpsのサービスコネクションで「Azure Resource Manager」を選択し、手動でサービスプリンシパルを設定。
    Azure DevOpsの対象のプロジェクトでProject Settings>Service connections>New service connectionを選択

Azure Resource Managerを選択

Service principal(manual)を選択

下記に示す設定を行い、Verify and saveを選択

説明
Environment Azure Cloud
Scope Level Subscription
Subscription Id AzureのサブスクリプションID
Subscription Name Azureのサブスクリプション名称
Service Principal Id 前段で作成したアプリケーション (クライアント) ID
Credential Service principal key
Service principal key 前段で作成したクライアントシークレット
Tenant Id 前段のディレクトリ (テナント) ID
Verify 押下し接続できることを確認
Service connection name 任意の値
Service Management Reference(optional) 任意の値
Description(optional) 任意の値
Security チェックオン
Verify and save 押下し保存

3.2 サンプル YAML

trigger:
  branches:
    include:
    - main
  paths:
    include:
    - src/*

variables:
  serviceConnectionName: '<your service connection>'
  containerRegistoryName: '<your acr name>'
  containerImageName: '<your acr image name>'
  containerImageTag: '<your acr image tag name>'

stages:
  # Publish
  - stage: DockerBuildAndPush
    displayName: 'Build and Push Docker Image'
    jobs:
    - job: BuildAndPushImage
      displayName: 'Build and Push Docker Image Job'
      pool:
        vmImage: 'ubuntu-latest'
      steps:
        - task: AzureCLI@2
          inputs:
            azureSubscription: $(serviceConnectionName)
            scriptType: 'bash'
            scriptLocation: 'inlineScript'
            inlineScript: |
              echo "Logging into Azure Container Registry"
              az acr login --name $(containerRegistoryName)

              echo "Building Docker image with Dockerfile"
              docker build -f $(Build.SourcesDirectory)/src/Dockerfile -t $(containerImageName):$(Build.BuildId) $(Build.SourcesDirectory)/src

              echo "Tagging Docker image"
              docker tag $(containerImageName):$(Build.BuildId) $(containerRegistoryName).azurecr.io/$(containerImageName):$(containerImageTag)

              echo "Pushing Docker image"
              docker push $(containerRegistoryName).azurecr.io/$(containerImageName):$(containerImageTag)
          displayName: 'Build, Tag, and Push Docker Image using Azure CLI'

説明

このYAMLスクリプトでは、AzureCLI@2タスクを使用してAzure CLIコマンドを実行し、異なるテナントのACRにDockerイメージをPushします。az acr loginコマンドでACRにログインし、DockerイメージをビルドしてPushするフローを手動でスクリプト化しています。

まとめ

同じテナント内のACRにはDocker Registryサービスコネクションを使用し、異なるテナントの場合はAzure Resource Managerサービスコネクションを手動で作成する必要があります。それぞれに応じた設定とYAMLの記述方法を活用し、効率的なCI/CDパイプラインを構築しましょう。

References

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/library/service-endpoints?view=azure-devops

GitHubで編集を提案

Discussion