Autenticazione tra più registri in un'attività del Registro Azure Container usando un'identità gestita da Azure

In un'attività del Registro Azure Container è possibile abilitare un'identità gestita per le risorse di Azure. L'attività può usare l'identità per accedere ad altre risorse di Azure, senza la necessità di specificare o gestire credenziali.

Questo articolo illustra come abilitare un'identità gestita in un'attività per eseguire il pull di un'immagine da un registro diverso da quello usato per eseguire l'attività.

Per creare le risorse di Azure, questo articolo richiede che venga eseguita l'interfaccia della riga di comando di Azure versione 2.0.68 o successiva. Eseguire az --version per trovare la versione. Se è necessario eseguire l'installazione o l'aggiornamento, vedere Installare l'interfaccia della riga di comando di Azure.

Panoramica dello scenario

L'attività di esempio esegue il pull di un'immagine di base da un altro registro contenitori di Azure per compilare ed eseguire il push di un'immagine dell'applicazione. Per eseguire il pull dell'immagine di base, configurare l'attività con un'identità gestita e assegnare le autorizzazioni appropriate.

Questo esempio illustra i passaggi con un'identità gestita assegnata dall'utente o dal sistema. La scelta dell'identità dipende dalle esigenze della propria organizzazione.

In uno scenario reale un'organizzazione potrebbe mantenere un set di immagini di base usate da tutti i team di sviluppo per compilare le applicazioni. Queste immagini di base vengono archiviate in un registro aziendale per cui ogni team di sviluppo ha solo i diritti di pull.

Prerequisiti

Per questo articolo sono necessari due registri contenitori di Azure:

  • Il primo registro si usa per creare ed eseguire attività del Registro Azure Container. In questo articolo questo registro è denominato myregistry.
  • Il secondo registro ospita un'immagine di base usata per l'attività di compilazione di un'immagine. In questo articolo il secondo registro di sistema è denominato mybaseregistry.

Sostituire i nomi dei registri con i propri valori nei passaggi successivi.

Se i registri contenitori di Azure necessari non sono disponibili, vedere Avvio rapido: Creare un registro contenitori privato usando l'interfaccia della riga di comando di Azure. Non è ancora necessario eseguire il push delle immagini nel registro.

Preparare il registro di base

A scopo dimostrativo, come operazione occasionale, eseguire [az acr import][az-acr-import] per importare un'immagine Node.js pubblica da Docker Hub al registro di base. In pratica, un altro team o processo nell'organizzazione potrebbe mantenere le immagini nel registro di base.

az acr import --name mybaseregistry \
  --source docker.io/library/node:15-alpine \
  --image baseimages/node:15-alpine 

Definire i passaggi dell'attività nel file YAML

La procedura questo esempio di attività in più passaggi è definita in un file YAML. Creare un file denominato helloworldtask.yaml nella directory di lavoro locale e incollare il contenuto seguente. Aggiornare il valore di REGISTRY_NAME nel passaggio di compilazione con il nome del server del registro di base.

version: v1.1.0
steps:
# Replace mybaseregistry with the name of your registry containing the base image
  - build: -t $Registry/hello-world:$ID  https://github.com/Azure-Samples/acr-build-helloworld-node.git#main -f Dockerfile-app --build-arg REGISTRY_NAME=mybaseregistry.azurecr.io
  - push: ["$Registry/hello-world:$ID"]

Il passaggio di compilazione usa il file di Dockerfile-app nel repository Azure-Samples/acr-build-helloworld-node per compilare un'immagine. --build-arg fa riferimento al registro di base per eseguire il pull dell'immagine di base. Dopo la compilazione viene eseguito il push dell'immagine nel registro usato per eseguire l'attività.

Opzione 1: Creare un'attività con un'identità assegnata dall'utente

I passaggi di questa sezione creano un'attività e abilitano un'identità assegnata dall'utente. Per abilitare invece un'identità assegnata dal sistema, vedere Opzione 2: Creare un'attività con un'identità assegnata dal sistema.

Creare un'identità assegnata dall'utente

Creare un'identità denominata myACRTasksId nella sottoscrizione usando il comando az identity create. È possibile usare lo stesso gruppo di risorse usato in precedenza per creare il registro contenitori oppure uno diverso.

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

Per configurare l'identità nei passaggi seguenti, usare il comando az identity show per archiviare l'ID risorsa, l'ID entità e l'ID client in variabili.

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

Creare un'attività

Creare l'attività helloworldtask eseguendo il comando az acr task create seguente. L'attività viene eseguita senza un contesto del codice sorgente e il comando fa riferimento al file helloworldtask.yaml nella directory di lavoro. Il parametro --assign-identity passa l'ID risorsa dell'identità assegnata dall'utente.

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

Nell'output del comando la sezione identity mostra che nell'attività è impostata l'identità di tipo UserAssigned:

[...]
"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"
      }
[...]

Assegnare all'identità le autorizzazioni per eseguire il pull dal registro di base

In questa sezione concedere all'identità gestita le autorizzazioni per eseguire il pull dal registro di base, mybaseregistry.

Usare il comando az acr show per ottenere l'ID risorsa del registro di base e archiviarlo in una variabile:

baseregID=$(az acr show --name mybaseregistry --query id --output tsv)

Usare il comando az role assignment create per assegnare all'identità il ruolo acrpull per il registro di base. Questo ruolo ha solo le autorizzazioni per eseguire il pull di immagini dal registro.

az role assignment create \
  --assignee $principalID \
  --scope $baseregID \
  --role acrpull

Passare ad Aggiungere le credenziali del Registro di sistema di destinazione all'attività.

Opzione 2: Creare un'attività con un'identità assegnata dal sistema

I passaggi di questa sezione creano un'attività e abilitano un'identità assegnata dal sistema. Per abilitare invece un'identità assegnata dall'utente, vedere Opzione 1: Creare un'attività con un'identità assegnata dall'utente.

Creare un'attività

Creare l'attività helloworldtask eseguendo il comando az acr task create seguente. L'attività viene eseguita senza un contesto del codice sorgente e il comando fa riferimento al file helloworldtask.yaml nella directory di lavoro. Il parametro --assign-identity senza valori abilita l'identità gestita assegnata dal sistema nell'attività.

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

Nell'output del comando la sezione identity mostra che nell'attività è impostata l'identità di tipo SystemAssigned. principalId è l'ID entità dell'identità dell'attività:

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

Usare il comando az acr task show per archiviare il valore di principalId in una variabile, da usare nei comandi successivi. Sostituire il nome dell'attività e del registro con i propri valori nel comando seguente:

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

Assegnare all'identità le autorizzazioni per eseguire il pull dal registro di base

In questa sezione concedere all'identità gestita le autorizzazioni per eseguire il pull dal registro di base, mybaseregistry.

Usare il comando az acr show per ottenere l'ID risorsa del registro di base e archiviarlo in una variabile:

baseregID=$(az acr show --name mybaseregistry --query id --output tsv)

Usare il comando az role assignment create per assegnare all'identità il ruolo acrpull per il registro di base. Questo ruolo ha solo le autorizzazioni per eseguire il pull di immagini dal registro.

az role assignment create \
  --assignee $principalID \
  --scope $baseregID \
  --role acrpull

Aggiungere le credenziali del registro di destinazione all'attività

Ora usare il comando az acr task credential add per consentire all'attività di eseguire l'autenticazione con il registro di base usando le credenziali dell'identità. Eseguire il comando corrispondente al tipo di identità gestita abilitata nell'attività. Se è stata abilitata un'identità assegnata dall'utente, passare --use-identity con l'ID client dell'identità. Se è stata abilitata un'identità assegnata dal sistema, passare --use-identity [system].

# Add credentials for user-assigned identity to the task
az acr task credential add \
  --name helloworldtask \
  --registry myregistry \
  --login-server mybaseregistry.azurecr.io \
  --use-identity $clientID

# Add credentials for system-assigned identity to the task
az acr task credential add \
  --name helloworldtask \
  --registry myregistry \
  --login-server mybaseregistry.azurecr.io \
  --use-identity [system]

Eseguire manualmente l'attività

Per verificare che l'attività in cui è stata abilitata un'identità gestita venga eseguita correttamente, attivarla manualmente con il comando az acr task run.

az acr task run \
  --name helloworldtask \
  --registry myregistry

Se l'attività viene eseguita correttamente, l'output è simile al seguente:

Queued a run with ID: cf10
Waiting for an agent...
2019/06/14 22:47:32 Using acb_vol_dbfbe232-fd76-4ca3-bd4a-687e84cb4ce2 as the home volume
2019/06/14 22:47:39 Creating Docker network: acb_default_network, driver: 'bridge'
2019/06/14 22:47:40 Successfully set up Docker network: acb_default_network
2019/06/14 22:47:40 Setting up Docker configuration...
2019/06/14 22:47:41 Successfully set up Docker configuration
2019/06/14 22:47:41 Logging in to registry: myregistry.azurecr.io
2019/06/14 22:47:42 Successfully logged into myregistry.azurecr.io
2019/06/14 22:47:42 Logging in to registry: mybaseregistry.azurecr.io
2019/06/14 22:47:43 Successfully logged into mybaseregistry.azurecr.io
2019/06/14 22:47:43 Executing step ID: acb_step_0. Timeout(sec): 600, Working directory: '', Network: 'acb_default_network'
2019/06/14 22:47:43 Scanning for dependencies...
2019/06/14 22:47:45 Successfully scanned dependencies
2019/06/14 22:47:45 Launching container with name: acb_step_0
Sending build context to Docker daemon   25.6kB
Step 1/6 : ARG REGISTRY_NAME
Step 2/6 : FROM ${REGISTRY_NAME}/baseimages/node:15-alpine
15-alpine: Pulling from baseimages/node
[...]
Successfully built 41b49a112663
Successfully tagged myregistry.azurecr.io/hello-world:cf10
2019/06/14 22:47:56 Successfully executed container: acb_step_0
2019/06/14 22:47:56 Executing step ID: acb_step_1. Timeout(sec): 600, Working directory: '', Network: 'acb_default_network'
2019/06/14 22:47:56 Pushing image: myregistry.azurecr.io/hello-world:cf10, attempt 1
The push refers to repository [myregistry.azurecr.io/hello-world]
[...]
2019/06/14 22:48:00 Step ID: acb_step_1 marked as successful (elapsed time in seconds: 2.517011)
2019/06/14 22:48:00 The following dependencies were found:
2019/06/14 22:48:00
- image:
    registry: myregistry.azurecr.io
    repository: hello-world
    tag: cf10
    digest: sha256:611cf6e3ae3cb99b23fadcd89fa144e18aa1b1c9171ad4a0da4b62b31b4e38d1
  runtime-dependency:
    registry: mybaseregistry.azurecr.io
    repository: baseimages/node
    tag: 15-alpine
    digest: sha256:e8e92cffd464fce3be9a3eefd1b65dc9cbe2484da31c11e813a4effc6105c00f
  git:
    git-head-revision: 0f988779c97fe0bfc7f2f74b88531617f4421643

Run ID: cf10 was successful after 32s

Eseguire il comando az acr repository show-tags per verificare che l'immagine sia stata compilata e che ne sia stato eseguito il push in myregistry:

az acr repository show-tags --name myregistry --repository hello-world --output tsv

Output di esempio:

cf10

Passaggi successivi