Compartilhar via


Autenticação externa em uma tarefa do ACR usando uma identidade gerenciada do Azure

Em uma tarefa do ACR, você pode habilitar uma identidade gerenciada para os recursos do Azure. A tarefa pode usar a identidade para acessar outros recursos Azure, sem a necessidade de fornecer ou gerenciar credenciais.

Neste artigo, você aprenderá a habilitar uma identidade gerenciada em uma tarefa que acessa os segredos armazenados em um cofre de chaves do Azure.

Para criar os recursos do Azure, este artigo requer que você execute a versão 2.0.68 ou posterior da CLI do Azure. Execute az --version para encontrar a versão. Se você precisa instalar ou atualizar, consulte Instalar a CLI do Azure.

Visão geral do cenário

A tarefa de exemplo lê as credenciais do Docker Hub armazenadas em um cofre de chaves do Azure. As credenciais são para uma conta do Docker Hub com permissões de gravação (push) para um repositório privado do Docker Hub. Para ler as credenciais, configure a tarefa com uma identidade gerenciada e atribua as permissões apropriadas a ela. A tarefa associada à identidade cria uma imagem e entra no Docker Hub para enviar a imagem por push ao repositório privado.

Este exemplo mostra as etapas usando uma identidade gerenciada atribuída pelo usuário ou pelo sistema. A sua escolha de identidade depende das necessidades da sua organização.

Em um cenário do mundo real, uma empresa pode publicar imagens em um repositório privado no Docker Hub como parte de um processo de compilação.

Pré-requisitos

Você precisa de um registro de contêiner do Azure no qual executa a tarefa. Neste artigo, esse registro é nomeado myregistry. Substitua por seu nome de registro em etapas posteriores.

Se você ainda não tem um registro de contêiner do Azure, confira Início Rápido: criar um registro de contêiner privado usando a CLI do Azure. Você ainda não precisa enviar imagens por push para o registro.

Você também precisa de um repositório privado no Docker Hub e uma conta do Docker Hub com permissões para gravar no repositório. Neste exemplo, esse repositório é chamado hubuser/hubrepo.

Criar um cofre de chaves e segredos de armazenamento

Se necessário, primeiro crie um grupo de recursos chamado myResourceGroup no local eastus com o seguinte comando az group create:

az group create --name myResourceGroup --location eastus

Use o comando az keyvault create para criar um cofre de chaves. Especifique um nome exclusivo de cofre de chaves.

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

Armazene as credenciais do Docker Hub necessárias no cofre de chaves usando o comando az keyvault secret set. Nestes comandos, os valores são transmitidos em variáveis de ambiente:

# 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

Em um cenário do mundo real, os segredos provavelmente seriam definidos e mantidos em um processo separado.

Definir as etapas de tarefa no arquivo YAML

As etapas para esta tarefa de exemplo são definidas em um arquivo YAML. Crie um arquivo chamado dockerhubtask.yaml em um diretório de trabalho local e cole o conteúdo a seguir. Substitua o nome do cofre de chaves no arquivo pelo nome do cofre de chaves.

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

As etapas da tarefa fazem o seguinte:

  • Gerenciar credenciais de segredo para autenticar com o Docker Hub.
  • Autenticar com o Docker Hub transmitindo os segredos para o comando docker login.
  • Criar uma imagem usando uma amostra do Dockerfile no repositório Azure-Samples/acr-tasks.
  • Enviar a imagem por push para o repositório privado do Docker Hub.

Opção 1: Criar tarefa com identidade atribuída pelo usuário

As etapas nesta seção criam uma tarefa e habilitam uma identidade atribuída pelo usuário. Se você quiser habilitar uma identidade atribuída pelo sistema, consulte Opção 2: Criar tarefa com identidade atribuída pelo usuário.

Criar uma identidade atribuída pelo usuário

Crie uma identidade chamada myACRTasksId na sua assinatura usando o comando az identity create. Você pode usar o mesmo grupo de recursos que você usou anteriormente para criar um registro de contêiner, ou pode usar um diferente.

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

Para configurar a identidade atribuída pelo usuário nas etapas a seguir, use o comando az identity show para armazenar a ID do recurso de identidade, a ID da entidade de segurança e a ID do cliente em variáveis.

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

Criar tarefa

Crie a tarefa dockerhubtask executando o comando az acr task create. A tarefa é executada sem um contexto de código-fonte, e o comando faz referência ao arquivo dockerhubtask.yaml no diretório de trabalho. O parâmetro --assign-identity passa a ID do recurso da identidade atribuída pelo usuário.

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

Na saída do comando, a seção identity mostra que a identidade do tipo UserAssigned está definida na tarefa:

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

Conceder acesso de identidade ao cofre de chaves

Execute o seguinte comando az keyvault set-policy para definir uma política de acesso no cofre de chaves. O exemplo a seguir permite que a identidade leia segredos do cofre de chaves.

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

Continue em Executar a tarefa manualmente.

Opção 2: Criar tarefa com identidade atribuída pelo sistema

As etapas nesta seção criam uma tarefa e habilitam uma identidade atribuída pelo sistema. Se você quiser habilitar uma identidade atribuída pelo usuário, consulte Opção 1: Criar tarefa com identidade atribuída pelo usuário.

Criar tarefa

Crie a tarefa dockerhubtask executando o comando az acr task create. A tarefa é executada sem um contexto de código-fonte, e o comando faz referência ao arquivo dockerhubtask.yaml no diretório de trabalho. O parâmetro --assign-identity sem valor habilita a identidade atribuída pelo sistema na tarefa.

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

Na saída do comando, a seção identity mostra que uma identidade do tipo SystemAssigned está definida na tarefa. A principalId é a ID da entidade de segurança da identidade da tarefa:

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

Use o comando az acr task show para armazenar a ID da entidade de segurança em uma variável e usá-la em comandos posteriores. Substitua o nome da tarefa e do registro no seguinte comando:

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

Conceder acesso de identidade ao cofre de chaves

Execute o seguinte comando az keyvault set-policy para definir uma política de acesso no cofre de chaves. O exemplo a seguir permite que a identidade leia segredos do cofre de chaves.

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

Executar a tarefa manualmente

Para verificar se a tarefa na qual você habilitou uma identidade gerenciada está sendo executada com sucesso, acione manualmente a tarefa com o comando az acr task run. O parâmetro --set é usado para transmitir o nome do repositório privado para a tarefa. Neste exemplo, o nome do repositório de espaço reservado é hubuser/hubrepo.

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

Quando a tarefa é executada com êxito, a saída mostra a autenticação bem-sucedida para o Docker Hub e a imagem é compilada e enviada por push com êxito para o repositório privado:

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

Para confirmar se a imagem foi enviada por push, verifique a marca ( cf24 neste exemplo) no repositório privado do Docker Hub.

Próximas etapas