Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
---
title: Integrate Azure Container Registry with Azure Kubernetes Service (AKS)
description: Learn how to integrate Azure Kubernetes Service (AKS) with Azure Container Registry (ACR).
ms.topic: concept-article
ms.date: 05/08/2026
author: davidsmatlak
ms.author: davidsmatlak
ms.tool: azure-cli, azure-powershell
ms.devlang: azurecli
ms.custom: devx-track-azurepowershell, devx-track-azurecli
zone_pivot_groups: cli-powershell-terraform
# Customer intent: As a cloud administrator, I want to integrate Azure Container Registry with Azure Kubernetes Service, so that I can streamline the deployment of container images and manage access permissions efficiently.
---
# Authenticate with Azure Container Registry (ACR) from Azure Kubernetes Service (AKS)
When using [Azure Container Registry (ACR)][acr-intro] with Azure Kubernetes Service (AKS), you need to establish an authentication mechanism. You can configure the required permissions between ACR and AKS using the Azure CLI, Azure PowerShell, or Azure portal. This article provides examples to configure authentication between these Azure services using the Azure CLI or Azure PowerShell.
The AKS to ACR integration assigns the [AcrPull role][acr-pull] to the [Microsoft Entra ID managed identity][aad-identity] associated with the agent pool in your AKS cluster. For more information on AKS managed identities, see [Summary of managed identities][summary-msi].
> [!IMPORTANT]
> There's a latency issue with Microsoft Entra groups when attaching ACR. If the `AcrPull` role is granted to a Microsoft Entra group and the kubelet identity is added to the group to complete the Azure role-based access control (Azure RBAC) configuration, there might be a delay before the RBAC group takes effect. If you're running automation that requires the Azure RBAC configuration to be complete, we recommend you use [Bring your own kubelet identity][byo-kubelet-identity] as a workaround. You can precreate a user-assigned identity, add it to the Microsoft Entra group, then use the identity as the kubelet identity to create an AKS cluster. This method ensures the identity is added to the Microsoft Entra group before a token is generated by kubelet, which avoids the latency issue.
> [!NOTE]
> This article covers automatic authentication between AKS and ACR. If you need to pull an image from a private external registry, use an [image pull secret][image-pull-secret].
> [!CAUTION]
> The AKS-ACR integration through `az aks --attach-acr` isn't supported for ABAC-enabled ACR registries where the role assignment permissions mode is set to "RBAC Registry + ABAC Repository Permissions." ABAC-enabled ACR registries require the [`Container Registry Repository Reader` role](/azure/role-based-access-control/built-in-roles#container-registry-repository-reader) instead of the `AcrPull` role for granting image pull permissions. For ABAC-enabled ACR registries, you shouldn't use `az aks --attach-acr` but instead manually assign the `Container Registry Repository Reader` role assignment using either the Azure portal, `az role assignment` CLI, or Azure Resource Manager. For more information on ABAC-enabled ACR registries, see [Azure attribute-based access control](https://aka.ms/acr/auth/abac).
In this walkthrough, you configure an Azure Kubernetes Service (AKS) cluster to securely pull images from an Azure Container Registry (ACR). In Azure CLI, use `--attach-acr`. In Terraform, assign the `AcrPull` role to the AKS kubelet managed identity. This guide follows the same flow as the Azure CLI workflow while using Terraform for infrastructure provisioning.
## Before you begin
- You need the [**Owner**][rbac-owner], [**Azure account administrator**][rbac-classic], or [**Azure co-administrator**][rbac-classic] role on your Azure subscription.
- To avoid the need for these roles, you can instead use an existing managed identity to authenticate ACR from AKS. For more information, see [Use an Azure managed identity to authenticate to an ACR](/azure/container-registry/container-registry-authentication-managed-identity).
:::zone pivot="azure-cli, terraform"
- If you're using Azure CLI, this article requires that you're running Azure CLI version 2.7.0 or later. to find the version, run the `az --version` command. If you need to install or upgrade, see [Install Azure CLI][azure-cli-install].
:::zone-end
:::zone pivot="azure-powershell"
- If you're using Azure PowerShell, this article requires that you're running Azure PowerShell version 5.9.0 or later. To find the version, run the `Get-InstalledModule -Name Az` command. If you need to install or upgrade, see [Install Azure PowerShell][azure-powershell-install].
- Examples and syntax to use Terraform for configuring ACR can be found in the [Terraform reference][terraform-reference].
:::zone-end
:::zone pivot="terraform"
- Terraform installed (`>= 1.6`).
- Azure CLI installed and signed in to your subscription.
- Permissions to assign roles (Owner or User Access Administrator).
In this article, you configure an Azure Kubernetes Service (AKS) cluster to securely pull images from an Azure Container Registry (ACR). In Azure CLI, use `--attach-acr`. In Terraform, assign the `AcrPull` role to the AKS kubelet managed identity.
This article follows the same flow as the Azure CLI workflow while using Terraform for infrastructure provisioning. To verify you're signed in to the correct subscription, use the following Azure CLI commands:
```azurecli-interactive
az login
az account show
```
:::zone-end
## Create a new ACR
:::zone pivot="azure-cli"
If you don't already have an ACR, create one using the [`az acr create`][az-acr-create] command.
The registry name must be globally unique within Azure, and contain 5-50 alphanumeric characters, excluding dash (`-`) characters. This name is part of the fully qualified DNS name of the registry.
```azurecli-interactive
export RANDOM_STRING=$(printf '%05d%05d' "$RANDOM" "$RANDOM")
export MYACR="mycontainerregistry$RANDOM_STRING"
export ACR_RESOURCE_GROUP="myContainerRegistryResourceGroup"
export LOCATION="westcentralus"
az group create \
--name $ACR_RESOURCE_GROUP \
--location $LOCATION
az acr create \
--name $MYACR \
--resource-group $ACR_RESOURCE_GROUP \
--sku basic
```
The `RANDOM_STRING` variable stores a random 10-digit string. The `MYACR` value is concatenated with the `RANDOM_STRING` value to create a unique name.
:::zone-end
:::zone pivot="azure-powershell"
If you don't already have an ACR, create one using the [`New-AzContainerRegistry`][new-azcontainerregistry] cmdlet.
The registry name must be globally unique within Azure, and contain 5-50 alphanumeric characters, excluding dash (`-`) characters. This name is part of the fully qualified DNS name of the registry.
```azurepowershell-interactive
$RandomString = (Get-Random -Minimum 1000000000 -Maximum 10000000000).ToString()
$MyAcr = "mycontainerregistry$RandomString"
$AcrResourceGroup = "myContainerRegistryResourceGroup"
$Location = "westcentralus"
New-AzResourceGroup -Name $AcrResourceGroup -Location $Location
$NewAcr = @{
Name = $MyAcr
ResourceGroupName = $AcrResourceGroup
Location = $Location
Sku = "Basic"
}
New-AzContainerRegistry @NewAcr
```
The `$RandomString` variable stores a random 10-digit string. The `$MyAcr` value is concatenated with the `$RandomString` value to create a unique name.
:::zone-end
:::zone pivot="terraform"
The Terraform sample in the next section creates the ACR as part of the complete AKS and ACR deployment.
:::zone-end
## Create a new AKS cluster and integrate with an existing ACR
:::zone pivot="azure-cli"
Create a new AKS cluster and integrate with an existing ACR using the [`az aks create`][az-aks-create] command with the [`--attach-acr`][cli-param] parameter. This command allows you to authorize an existing ACR in your subscription and configures the appropriate `AcrPull` role for the managed identity.
```azurecli-interactive
export CLUSTER_NAME="myAKSCluster"
export CLUSTER_RESOURCE_GROUP="myClusterResourceGroup"
az group create \
--name $CLUSTER_RESOURCE_GROUP \
--location $LOCATION
az aks create \
--name $CLUSTER_NAME \
--resource-group $CLUSTER_RESOURCE_GROUP \
--generate-ssh-keys \
--attach-acr $MYACR
```
### Use an ACR in a different subscription or attach using resource ID
If you're using an ACR located in a different subscription from your AKS cluster or would prefer to use the ACR _resource ID_ instead of the ACR name, use the following syntax. This example creates the `ACR_RESOURCE_ID` variable using the container registry created in the previous section.
```azurecli
ACR_RESOURCE_ID=$(az acr show \
--name $MYACR \
--resource-group $ACR_RESOURCE_GROUP \
--query id --output tsv)
az aks create \
--name $CLUSTER_NAME \
--resource-group $CLUSTER_RESOURCE_GROUP \
--generate-ssh-keys \
--attach-acr $ACR_RESOURCE_ID
```
:::zone-end
:::zone pivot="azure-powershell"
Create a new AKS cluster and integrate with an existing ACR using the [`New-AzAksCluster`][new-azakscluster] cmdlet with the [`-AcrNameToAttach`][ps-attach] parameter. This command allows you to authorize an existing ACR in your subscription and configures the appropriate `AcrPull` role for the managed identity.
```azurepowershell-interactive
$ClusterName = "myAKSCluster"
$ClusterResourceGroup = "myClusterResourceGroup"
New-AzResourceGroup -Name $ClusterResourceGroup -Location $Location
$NewCluster = @{
Name = $ClusterName
ResourceGroupName = $ClusterResourceGroup
GenerateSshKey = $true
AcrNameToAttach = $MyAcr
}
New-AzAksCluster @NewCluster
```
### Use an ACR in a different subscription or attach using resource ID
Azure PowerShell only supports attaching ACR to AKS using the `-AcrNameToAttach` parameter and doesn't support attaching to an ACR by _resource ID_.
:::zone-end
:::zone pivot="terraform"
Create a _main.tf_ file and copy the following tested sample configuration into it. The Azure Terraform GitHub repository maintains the sample in the [Azure Terraform GitHub repository][terraform-sample]. The sample creates an ACR and an AKS cluster, assigns the `AcrPull` role to the kubelet managed identity, imports an NGINX image into the registry, and deploys that image to the cluster.
[!code-terraform[master](~/terraform_samples/quickstart/101-aks-acr-auth/main.tf)]
:::zone-end
## Configure ACR integration for an existing AKS cluster
You can attach an ACR to an existing AKS cluster, or detach an ACR from an AKS cluster if you no longer want the cluster to have access to the registry.
The previous examples in the article created an Azure Container Registry and an Azure Kubernetes Service cluster attached to the ACR. The following are examples of how to attach or detach a container registry from a cluster and use the ACR and AKS cluster created in this article. You can replace the variable values with your own ACR and AKS cluster values.
### Attach an ACR to an existing AKS cluster
:::zone pivot="azure-cli"
Integrate an existing ACR with an existing AKS cluster using the [`az aks update`][az-aks-update] command with the [`--attach-acr`][cli-param] parameter.
```azurecli-interactive
# Attach using acr-name
az aks update \
--name $CLUSTER_NAME \
--resource-group $CLUSTER_RESOURCE_GROUP \
--attach-acr $MYACR
# Attach using acr-resource-id
az aks update \
--name $CLUSTER_NAME \
--resource-group $CLUSTER_RESOURCE_GROUP \
--attach-acr $ACR_RESOURCE_ID
```
The `az aks update --attach-acr` command uses the permissions of the user running the command to create the ACR role assignment. This role is assigned to the [kubelet][kubelet] managed identity. For more information on AKS managed identities, see [Summary of managed identities][summary-msi].
:::zone-end
:::zone pivot="azure-powershell"
Integrate an existing ACR with an existing AKS cluster using the [`Set-AzAksCluster`][set-azakscluster] command with the [`-AcrNameToAttach`][ps-attach] parameter.
```azurepowershell-interactive
$AttachCluster = @{
Name = $ClusterName
ResourceGroupName = $ClusterResourceGroup
AcrNameToAttach = $MyAcr
}
Set-AzAksCluster @AttachCluster
```
The `Set-AzAksCluster -AcrNameToAttach` cmdlet uses the permissions of the user running the command to create the role ACR assignment. This role is assigned to the [kubelet][kubelet] managed identity. For more information on AKS managed identities, see [Summary of managed identities][summary-msi].
:::zone-end
:::zone pivot="terraform"
The tested Terraform sample creates new AKS and ACR resources. To integrate existing resources, use the Azure CLI or Azure PowerShell tab, or adapt the sample's `AcrPull` role assignment to reference your existing resources.
:::zone-end
### Detach an ACR from an AKS cluster
:::zone pivot="azure-cli"
Remove the integration between an ACR and an AKS cluster using the [`az aks update`][az-aks-update] command with the [`--detach-acr`][cli-param] parameter.
```azurecli-interactive
# Detach using acr-name
az aks update \
--name $CLUSTER_NAME \
--resource-group $CLUSTER_RESOURCE_GROUP \
--detach-acr $MYACR
# Detach using acr-resource-id
az aks update \
--name $CLUSTER_NAME \
--resource-group $CLUSTER_RESOURCE_GROUP \
--detach-acr $ACR_RESOURCE_ID
```
:::zone-end
:::zone pivot="azure-powershell"
Remove the integration between an ACR and an AKS cluster using the [`Set-AzAksCluster`][set-azakscluster] command with the [`-AcrNameToDetach`][ps-detach] parameter.
```azurepowershell-interactive
$DetachCluster = @{
Name = $ClusterName
ResourceGroupName = $ClusterResourceGroup
AcrNameToDetach = $MyAcr
}
Set-AzAksCluster @DetachCluster
```
:::zone-end
:::zone pivot="terraform"
The tested Terraform sample doesn't define a standalone detach workflow. To revoke access while preserving the AKS and ACR resources, remove both the `kubernetes_deployment_v1.nginx` and `azurerm_role_assignment.aks_acr_pull` resources from your configuration, and then apply the updated Terraform plan.
:::zone-end
:::zone pivot="terraform"
## Initialize and deploy the configuration
After your configuration is complete, initialize Terraform and review the execution plan before applying.
```bash
terraform fmt
terraform init
terraform validate
terraform plan
terraform apply
```
At this point, your AKS cluster is configured to pull images from ACR.
You can now:
- Import images into ACR.
- Deploy workloads to AKS.
- Verify pod deployment.
:::zone-end
## Working with ACR and AKS
Import an image into your ACR, then deploy that image to your AKS cluster.
### Import an image into your ACR
:::zone pivot="azure-cli"
Import an image from Docker Hub into your ACR using the [`az acr import`][az-acr-import] command.
```azurecli-interactive
az acr import \
--name $MYACR \
--source docker.io/library/nginx:latest \
--image nginx:v1
```
Run the following commands to verify the image was imported.
```azurecli-interactive
az acr repository show --name $MYACR --repository nginx
az acr repository show-tags --name $MYACR --repository nginx
```
:::zone-end
:::zone pivot="terraform"
The Terraform sample imports the NGINX image into ACR during deployment.
:::zone-end
:::zone pivot="azure-powershell"
Import an image from Docker Hub into your ACR using the [`Import-AzContainerRegistryImage`][import-azcontainerregistryimage] cmdlet.
```azurepowershell-interactive
$ImportImage = @{
RegistryName = $MyAcr
ResourceGroupName = $AcrResourceGroup
SourceRegistryUri = 'docker.io'
SourceImage = 'library/nginx:latest'
TargetTag = 'nginx:v1'
}
Import-AzContainerRegistryImage @ImportImage
```
Run the following commands to verify the image was imported.
```azurepowershell-interactive
Get-AzContainerRegistryRepository -RegistryName $MyAcr
Get-AzContainerRegistryTag -RegistryName $MyAcr -Repository nginx
```
:::zone-end
### Create deployment file
Create a Kubernetes deployment that references the image you imported into ACR. If the deployment is successful and the image is pulled correctly, your AKS cluster is properly integrated with ACR.
Create a file named _acr-nginx.yaml_ using the following sample YAML. In the `image` property, replace _acr-name_ with the name of your ACR. In Azure CLI, run `echo $MYACR` to display the ACR name. In Azure PowerShell, run `$MyAcr` to display the ACR name.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx0-deployment
labels:
app: nginx0-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx0
template:
metadata:
labels:
app: nginx0
spec:
containers:
- name: nginx
image: <acr-name>.azurecr.io/nginx:v1
ports:
- containerPort: 80
```
### Get credentials and run deployment
:::zone pivot="azure-cli"
1. Ensure you have the proper AKS credentials using the [`az aks get-credentials`][az-aks-get-credentials] command.
```azurecli-interactive
az aks get-credentials \
--resource-group $CLUSTER_RESOURCE_GROUP \
--name $CLUSTER_NAME
```
1. Run the deployment in your AKS cluster using the `kubectl apply` command.
```shell
kubectl apply -f acr-nginx.yaml
```
1. Monitor the deployment using the `kubectl get pods` command.
```shell
kubectl get pods
```
The output should show two running pods, as shown in the following example output:
```output
NAME READY STATUS RESTARTS AGE
nginx0-deployment-669dfc4d4b-x74kr 1/1 Running 0 20s
nginx0-deployment-669dfc4d4b-xdpd6 1/1 Running 0 20s
```
:::zone-end
:::zone pivot="terraform"
The Terraform sample configures the Kubernetes provider and deploys the NGINX workload during `terraform apply`. Get the cluster credentials, and then verify the deployment:
```bash
RESOURCE_GROUP=$(terraform output -raw resource_group_name)
CLUSTER_NAME=$(terraform output -raw aks_cluster_name)
az aks get-credentials \
--resource-group $RESOURCE_GROUP \
--name $CLUSTER_NAME
kubectl get pods
```
:::zone-end
:::zone pivot="azure-powershell"
1. Ensure you have the proper AKS credentials using the [`Import-AzAksCredential`][import-azakscredential] cmdlet.
```azurepowershell-interactive
Import-AzAksCredential -ResourceGroupName $ClusterResourceGroup -Name $ClusterName
```
1. Run the deployment in your AKS cluster using the `kubectl apply` command.
```shell
kubectl apply -f acr-nginx.yaml
```
1. Monitor the deployment using the `kubectl get pods` command.
```shell
kubectl get pods
```
The output should show two running pods, as shown in the following example output:
```output
NAME READY STATUS RESTARTS AGE
nginx0-deployment-669dfc4d4b-x74kr 1/1 Running 0 20s
nginx0-deployment-669dfc4d4b-xdpd6 1/1 Running 0 20s
```
:::zone-end
### Troubleshooting
- Validate the registry is accessible from the AKS cluster using the [`az aks check-acr`](/cli/azure/aks#az-aks-check-acr) command.
- If your AKS cluster uses an HTTP proxy and your ACR uses Private Link, add both ACR endpoints (REST and data) to the cluster `noProxy` list. For more information, see [HTTP proxy support in Azure Kubernetes Service (AKS)](/azure/aks/http-proxy).
- Learn more about [ACR monitoring](/azure/container-registry/monitor-service).
- Learn more about [ACR health](/azure/container-registry/container-registry-check-health).
## Clean up resources
When you no longer need the resources created in this article, you can delete the resource groups to remove all associated resources. These commands delete the ACR and AKS cluster and the clusters node resource group that begins with `MC_`.
:::zone pivot="azure-cli"
```azurecli-interactive
az group delete --name $ACR_RESOURCE_GROUP --yes --no-wait
az group delete --name $CLUSTER_RESOURCE_GROUP --yes --no-wait
```
:::zone-end
:::zone pivot="terraform"
Run the following command from the directory that contains the Terraform configuration:
```bash
terraform destroy
```
:::zone-end
:::zone pivot="azure-powershell"
```azurepowershell-interactive
Remove-AzResourceGroup -Name $AcrResourceGroup -Force
Remove-AzResourceGroup -Name $ClusterResourceGroup -Force
```
:::zone-end
## Related content
- [Use a managed identity to authenticate to an Azure container registry](/azure/container-registry/container-registry-authentication-managed-identity)
- [HTTP proxy support in Azure Kubernetes Service (AKS)](/azure/aks/http-proxy)
<!-- LINKS EXTERNAL -->
[image-pull-secret]: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
[kubelet]: https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/
[terraform-reference]: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/container_registry
[terraform-sample]: https://github.com/Azure/terraform/tree/master/quickstart/101-aks-acr-auth
<!-- LINKS INTERNAL -->
[byo-kubelet-identity]: use-managed-identity.md#create-a-kubelet-managed-identity
[summary-msi]: managed-identity-overview.md#summary-of-managed-identities-used-by-aks
[acr-pull]: /azure/role-based-access-control/built-in-roles#acrpull
[azure-cli-install]: /cli/azure/install-azure-cli
[azure-powershell-install]: /powershell/azure/install-az-ps
[acr-intro]: /azure/container-registry/container-registry-intro
[aad-identity]: /azure/active-directory/managed-identities-azure-resources/overview
[rbac-owner]: /azure/role-based-access-control/built-in-roles#owner
[rbac-classic]: /azure/role-based-access-control/rbac-and-directory-admin-roles#classic-subscription-administrator-roles
[ps-detach]: /powershell/module/az.aks/set-azakscluster#-acrnametodetach
[cli-param]: /cli/azure/aks#az-aks-update-optional-parameters
[ps-attach]: /powershell/module/az.aks/set-azakscluster#-acrnametoattach
[az-acr-import]: /cli/azure/acr#az-acr-import
[az-aks-get-credentials]: /cli/azure/aks#az-aks-get-credentials
[import-azakscredential]: /powershell/module/az.aks/import-azakscredential
[import-azcontainerregistryimage]: /powershell/module/az.containerregistry/import-azcontainerregistryimage
[set-azakscluster]: /powershell/module/az.aks/set-azakscluster
[az-aks-update]: /cli/azure/aks#az-aks-update
[new-azakscluster]: /powershell/module/az.aks/new-azakscluster
[az-aks-create]: /cli/azure/aks#az-aks-create
[az-acr-create]: /cli/azure/acr#az-acr-create
[new-azcontainerregistry]: /powershell/module/az.containerregistry/new-azcontainerregistry