Azure マネージド ID を使用した、ACR タスクでの外部認証

ACR タスクで、Azure リソースのマネージド ID を有効にすることができます。 その ID をタスクで使用すれば、資格情報を渡したり管理したりしなくても、他の Azure リソースにアクセスすることができます。

この記事では、Azure キー コンテナーに格納されたシークレットにアクセスするタスクでマネージド ID を有効にする方法を説明します。

Azure リソースを作成するために、この記事では Azure CLI バージョン 2.0.68 以降を実行する必要があります。 バージョンを確認するには、az --version を実行します。 インストールまたはアップグレードする必要がある場合は、Azure CLI のインストールに関するページを参照してください。

シナリオの概要

この例のタスクでは、Azure キー コンテナーに格納されている Docker Hub の資格情報を読み取ります。 この資格情報は、Docker Hub のプライベート リポジトリに対する書き込み (プッシュ) アクセス許可を持つ Docker Hub アカウント用です。 資格情報を読み取るために、マネージド ID を使用してタスクを構成し、それに適切なアクセス許可を割り当てます。 この ID を関連付けるタスクでは、イメージを作成し、Docker Hub にサインインして、そのイメージをプライベート リポジトリにプッシュします。

この例では、ユーザー割り当てのマネージド ID またはシステム割り当てのマネージド ID を使用する手順について説明します。 どちらの ID を選ぶかは、所属する組織のニーズによって異なります。

実際のシナリオでは、企業がビルド プロセスの一環として、Docker Hub のプライベート リポジトリにイメージを発行することが考えられます。

前提条件

タスクの実行場所となる Azure コンテナー レジストリが必要です。 この記事では、このレジストリの名前を myregistry にします。 後のステップで、独自のレジストリ名に置き換えてください。

まだ Azure コンテナー レジストリがない場合は、「クイック スタート: Azure CLI を使用したプライベート コンテナー レジストリの作成」を参照してください。 まだレジストリにイメージをプッシュする必要はありません。

また、Docker Hub のプライベート リポジトリと、そのリポジトリへの書き込みアクセス許可のある Docker Hub アカウントが必要となります。 この例では、このリポジトリの名前を hubuser/hubrepo にします。

キー コンテナーを作成してシークレットを格納する

まず、必要な場合は、次の az group create コマンドを使って、myResourceGroup という名前のリソース グループを eastus の場所に作成します。

az group create --name myResourceGroup --location eastus

キー コンテナーを作成するには、az keyvault create コマンドを使います。 必ず一意のキー コンテナー名を指定してください。

az keyvault create --name mykeyvault --resource-group myResourceGroup --location eastus

az keyvault secret set コマンドを使って、必要な Docker Hub の資格情報をキー コンテナーに格納します。 これらのコマンドで、値が環境変数に渡されます。

# Store Docker Hub user name
az keyvault secret set \
  --name UserName \
  --value $USERNAME \
  --vault-name mykeyvault

# Store Docker Hub password
az keyvault secret set \
  --name Password \
  --value $PASSWORD \
  --vault-name mykeyvault

実際のシナリオでは、シークレットを別個のプロセスで設定、管理するケースが多いでしょう。

タスクのステップを YAML ファイルで定義する

このタスク例のステップは、YAML ファイルで定義されています。 ローカル作業ディレクトリに dockerhubtask.yaml という名前のファイルを作成し、次の内容を貼り付けます。 ファイル内のキー コンテナーの名前を、実際のキー コンテナーの名前に置き換えてください。

version: v1.1.0
# Replace mykeyvault with the name of your key vault
secrets:
  - id: username
    keyvault: https://mykeyvault.vault.azure.net/secrets/UserName
  - id: password
    keyvault: https://mykeyvault.vault.azure.net/secrets/Password
steps:
# Log in to Docker Hub
  - cmd: bash echo '{{.Secrets.password}}' | docker login --username '{{.Secrets.username}}' --password-stdin 
# Build image
  - build: -t {{.Values.PrivateRepo}}:$ID https://github.com/Azure-Samples/acr-tasks.git -f hello-world.dockerfile
# Push image to private repo in Docker Hub
  - push:
    - {{.Values.PrivateRepo}}:$ID

このタスク ステップにより、次の作業が行われます。

  • Docker Hub に対して認証を行うためのシークレットの資格情報を管理します。
  • シークレットを docker login コマンドに渡して Docker Hub に対して認証を行います。
  • Azure-Samples/acr-tasks リポジトリ内のサンプル Dockerfile を使用してイメージを作成します。
  • プライベート Docker Hub リポジトリにイメージをプッシュします。

オプション 1: ユーザー割り当て ID を使用してタスクを作成する

このセクションの手順では、タスクを作成してユーザー割り当て ID を有効にします。 システム割り当て ID を有効にする場合は、「オプション 2: システム割り当て ID を使用してタスクを作成する」を参照してください。

ユーザー割り当て ID を作成する

az identity create コマンドを使って、サブスクリプションに myACRTasksId という名前の ID を作成します。 前にコンテナー レジストリを作成するために使ったものと同じリソース グループ、または別のリソース グループを使用できます。

az identity create \
  --resource-group myResourceGroup \
  --name myACRTasksId

後の手順でユーザー割り当て ID を構成するために、az identity show コマンドを使用して、ID のリソース ID、プリンシパル ID、およびクライアント ID を変数に保存します。

# Get resource ID of the user-assigned identity
resourceID=$(az identity show \
  --resource-group myResourceGroup \
  --name myACRTasksId \
  --query id --output tsv)

# Get principal ID of the task's user-assigned identity
principalID=$(az identity show \
  --resource-group myResourceGroup \
  --name myACRTasksId \
  --query principalId --output tsv)

# Get client ID of the user-assigned identity
clientID=$(az identity show \
  --resource-group myResourceGroup \
  --name myACRTasksId \
  --query clientId --output tsv)

タスクを作成する

以下の az acr task create コマンドを実行して、dockerhubtask タスクを作成します。 このタスクはソース コードのコンテキストなしで実行され、このコマンドは作業ディレクトリ内のファイル dockerhubtask.yaml を参照します。 ユーザー割り当て ID のリソース ID を --assign-identity パラメーターで渡します。

az acr task create \
  --name dockerhubtask \
  --registry myregistry \
  --context /dev/null \
  --file dockerhubtask.yaml \
  --assign-identity $resourceID

コマンドの出力の identity セクションでは、タスクで UserAssigned 型の ID が設定されたことが示されています。

[...]
"identity": {
    "principalId": null,
    "tenantId": null,
    "type": "UserAssigned",
    "userAssignedIdentities": {
      "/subscriptions/xxxxxxxx-d12e-4760-9ab6-xxxxxxxxxxxx/resourcegroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myACRTasksId": {
        "clientId": "xxxxxxxx-f17e-4768-bb4e-xxxxxxxxxxxx",
        "principalId": "xxxxxxxx-1335-433d-bb6c-xxxxxxxxxxxx"
      }
[...]

ID にキー コンテナーへのアクセスを許可する

次の az keyvault set-policy コマンドを実行して、キー コンテナーに対するアクセス ポリシーを設定します。 次の例では、ID にキー コンテナーからのシークレットの読み取りを許可します。

az keyvault set-policy --name mykeyvault \
  --resource-group myResourceGroup \
  --object-id $principalID \
  --secret-permissions get

タスクを手動で実行する」に進んでください。

オプション 2:システム割り当て ID を使用してタスクを作成する

このセクションの手順では、タスクを作成してシステム割り当て ID を有効にします。 ユーザー割り当て ID を有効にする場合は、「オプション 1: ユーザー割り当て ID を使用してタスクを作成する」を参照してください。

タスクを作成する

以下の az acr task create コマンドを実行して、dockerhubtask タスクを作成します。 このタスクはソース コードのコンテキストなしで実行され、このコマンドは作業ディレクトリ内のファイル dockerhubtask.yaml を参照します。 --assign-identity パラメーターを値なしで指定すると、システム割り当て ID がタスクで有効になります。

az acr task create \
  --name dockerhubtask \
  --registry myregistry \
  --context /dev/null \
  --file dockerhubtask.yaml \
  --assign-identity 

コマンドの出力の identity セクションでは、タスクで SystemAssigned 型の ID が設定されたことが示されています。 principalId は、タスク ID のプリンシパル ID です。

[...]
  "identity": {
    "principalId": "xxxxxxxx-2703-42f9-97d0-xxxxxxxxxxxx",
    "tenantId": "xxxxxxxx-86f1-41af-91ab-xxxxxxxxxxxx",
    "type": "SystemAssigned",
    "userAssignedIdentities": null
  },
  "location": "eastus",
[...]

後のコマンドで使用するため、az acr task show コマンドを使用して、この principalId を変数に格納します。 次のコマンドでは、タスクとレジストリの名前を置き換えます。

principalID=$(az acr task show \
  --name <task_name> --registry <registry_name> \
  --query identity.principalId --output tsv)

ID にキー コンテナーへのアクセスを許可する

次の az keyvault set-policy コマンドを実行して、キー コンテナーに対するアクセス ポリシーを設定します。 次の例では、ID にキー コンテナーからのシークレットの読み取りを許可します。

az keyvault set-policy --name mykeyvault \
  --resource-group myResourceGroup \
  --object-id $principalID \
  --secret-permissions get

タスクを手動で実行する

マネージド ID を有効にしたタスクが正常に実行されていることを確認するには、az acr task run コマンドを使用してタスクを手動でトリガーします。 --set パラメーターを使用して、プライベート リポジトリの名前をタスクに渡します。 この例では、プレースホルダー リポジトリの名前を hubuser/hubrepo にします。

az acr task run --name dockerhubtask --registry myregistry --set PrivateRepo=hubuser/hubrepo

タスクが正常に実行されたときは、出力結果を見ると、Docker Hub に対する認証が成功したこと、またイメージが正常に作成されてプライベート リポジトリにプッシュされたことがわかります。

Queued a run with ID: cf24
Waiting for an agent...
2019/06/20 18:05:55 Using acb_vol_b1edae11-30de-4f2b-a9c7-7d743e811101 as the home volume
2019/06/20 18:05:58 Creating Docker network: acb_default_network, driver: 'bridge'
2019/06/20 18:05:58 Successfully set up Docker network: acb_default_network
2019/06/20 18:05:58 Setting up Docker configuration...
2019/06/20 18:05:59 Successfully set up Docker configuration
2019/06/20 18:05:59 Logging in to registry: myregistry.azurecr.io
2019/06/20 18:06:00 Successfully logged into myregistry.azurecr.io
2019/06/20 18:06:00 Executing step ID: acb_step_0. Timeout(sec): 600, Working directory: '', Network: 'acb_default_network'
2019/06/20 18:06:00 Launching container with name: acb_step_0
[...]
Login Succeeded
2019/06/20 18:06:02 Successfully executed container: acb_step_0
2019/06/20 18:06:02 Executing step ID: acb_step_1. Timeout(sec): 600, Working directory: '', Network: 'acb_default_network'
2019/06/20 18:06:02 Scanning for dependencies...
2019/06/20 18:06:04 Successfully scanned dependencies
2019/06/20 18:06:04 Launching container with name: acb_step_1
Sending build context to Docker daemon    129kB
[...]
2019/06/20 18:06:07 Successfully pushed image: hubuser/hubrepo:cf24
2019/06/20 18:06:07 Step ID: acb_step_0 marked as successful (elapsed time in seconds: 2.064353)
2019/06/20 18:06:07 Step ID: acb_step_1 marked as successful (elapsed time in seconds: 2.594061)
2019/06/20 18:06:07 Populating digests for step ID: acb_step_1...
2019/06/20 18:06:09 Successfully populated digests for step ID: acb_step_1
2019/06/20 18:06:09 Step ID: acb_step_2 marked as successful (elapsed time in seconds: 2.743923)
2019/06/20 18:06:09 The following dependencies were found:
2019/06/20 18:06:09
- image:
    registry: registry.hub.docker.com
    repository: hubuser/hubrepo
    tag: cf24
    digest: sha256:92c7f9c92844bbbb5d0a101b22f7c2a7949e40f8ea90c8b3bc396879d95e899a
  runtime-dependency:
    registry: registry.hub.docker.com
    repository: library/hello-world
    tag: latest
    digest: sha256:0e11c388b664df8a27a901dce21eb89f11d8292f7fca1b3e3c4321bf7897bffe
  git:
    git-head-revision: b0ffa6043dd893a4c75644c5fed384c82ebb5f9e

Run ID: cf24 was successful after 15s

イメージがプッシュされたことを確認するには、プライベート Docker Hub リポジトリでタグ (この例では cf24) をチェックします。

次のステップ