Proposed Pull Request Change

title description ms.topic ms.date author ms.author ms.tool ms.devlang ms.custom zone_pivot_groups
Integrate Azure Container Registry with Azure Kubernetes Service (AKS) Learn how to integrate Azure Kubernetes Service (AKS) with Azure Container Registry (ACR). concept-article 05/08/2026 davidsmatlak davidsmatlak azure-cli, azure-powershell azurecli devx-track-azurepowershell, devx-track-azurecli cli-powershell-terraform
📄 Document Links
GitHub View on GitHub Microsoft Learn View on Microsoft Learn
⚠ Content Truncation Detected
The generated rewrite appears to be incomplete.
Original lines: -
Output lines: -
Ratio: -
Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
+0 -0
+0 -0
--- 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
Success! Branch created successfully. Create Pull Request on GitHub
Error: