Use a managed identity in Azure Kubernetes Service (AKS)

Azure Kubernetes Service (AKS) clusters require an identity to access Azure resources like load balancers and managed disks. The identity can be a managed identity or a service principal.

This article provides details on how to enable the following managed identity types on a new or existing AKS cluster:

  • System-assigned managed identity
  • Bring your own user-assigned managed identity
  • Pre-created Kubelet managed identity

Overview

When you deploy an AKS cluster, a system-assigned managed identity is automatically created, and it's managed by the Azure platform, so it doesn't require you to provision or rotate any secrets. For more information, see managed identities for Azure resources.

AKS doesn't automatically create a service principal, so you have to create one. Clusters that use a service principal eventually expire, and the service principal must be renewed to avoid impacting cluster authentication with the identity. Managing service principals adds complexity, so it's easier to use managed identities instead. The same permission requirements apply for both service principals and managed identities. Managed identities use certificate-based authentication. Each managed identity's credentials have an expiration of 90 days and are rolled after 45 days.

AKS uses both system-assigned and user-assigned managed identity types, and these identities are immutable.

Important

The open source Microsoft Entra pod-managed identity (preview) in Azure Kubernetes Service was deprecated on 10/24/2022, and the project archived in Sept. 2023. For more information, see the deprecation notice. The AKS Managed add-on begins deprecation in Sept. 2024.

We recommend you first review Microsoft Entra Workload ID overview. This authentication method replaces Microsoft Entra pod-managed identity (preview) and is the recommended method.

Before you begin

Limitations

  • Tenants moving or migrating a managed identity-enabled cluster isn't supported.
  • If the cluster has Microsoft Entra pod-managed identity (aad-pod-identity) enabled, Node-Managed Identity (NMI) pods modify the iptables of the nodes to intercept calls to the Azure Instance Metadata (IMDS) endpoint. This configuration means any request made to the Metadata endpoint is intercepted by NMI, even if the pod doesn't use aad-pod-identity. AzurePodIdentityException CRD can be configured to inform aad-pod-identity of any requests to the Metadata endpoint originating from a pod that matches labels defined in CRD should be proxied without any processing in NMI. The system pods with kubernetes.azure.com/managedby: aks label in kube-system namespace should be excluded in aad-pod-identity by configuring the AzurePodIdentityException CRD.
  • AKS doesn't support the use of a system-assigned managed identity when using a custom private DNS zone.

Summary of managed identities

AKS uses several managed identities for built-in services and add-ons.

Identity Name Use case Default permissions Bring your own identity
Control plane AKS Cluster Name Used by AKS control plane components to manage cluster resources including ingress load balancers and AKS-managed public IPs, Cluster Autoscaler, Azure Disk, File, Blob CSI drivers. Contributor role for Node resource group Supported
Kubelet AKS Cluster Name-agentpool Authentication with Azure Container Registry (ACR). N/A (for kubernetes v1.15+) Supported
Add-on AzureNPM No identity required. N/A No
Add-on AzureCNI network monitoring No identity required. N/A No
Add-on azure-policy (gatekeeper) No identity required. N/A No
Add-on azure-policy No identity required. N/A No
Add-on Calico No identity required. N/A No
Add-on Dashboard No identity required. N/A No
Add-on application-routing Manages Azure DNS and Azure Key Vault certificates Key Vault Secrets User role for Key Vault, DNZ Zone Contributor role for DNS zone No
Add-on HTTPApplicationRouting Manages required network resources. Reader role for node resource group, contributor role for DNS zone No
Add-on Ingress application gateway Manages required network resources. Contributor role for node resource group No
Add-on omsagent Used to send AKS metrics to Azure Monitor. Monitoring Metrics Publisher role No
Add-on Virtual-Node (ACIConnector) Manages required network resources for Azure Container Instances (ACI). Contributor role for node resource group No
Add-on Cost analysis Used to gather cost allocation data
OSS project Microsoft Entra ID-pod-identity Enables applications to access cloud resources securely with Microsoft Entra ID. N/A Steps to grant permission at Microsoft Entra Pod Identity Role Assignment configuration.

Enable managed identities on a new AKS cluster

Note

AKS creates a user-assigned kubelet identity in the node resource group if you don't specify your own kubelet managed identity.

Note

If your cluster is already using managed identity and the identity was changed, for example you update the cluster identity type from system-assigned to user-assigned, there is a delay for control plane components to switch to the new identity. Control plane components keep using the old identity until its token expires. After the token is refreshed, they switch to the new identity. This process can take several hours.

  1. Create an Azure resource group using the az group create command.

    az group create --name myResourceGroup --location westus2
    
  2. Create an AKS cluster using the az aks create command.

    az aks create -g myResourceGroup -n myManagedCluster --enable-managed-identity
    
  3. Get credentials to access the cluster using the az aks get-credentials command.

    az aks get-credentials --resource-group myResourceGroup --name myManagedCluster
    

Enable managed identities on an existing AKS cluster

To update your existing AKS cluster that's using a service principal to use a system-assigned managed identity, run the az aks update command.

az aks update -g myResourceGroup -n myManagedCluster --enable-managed-identity

After updating your cluster, the control plane and pods use the managed identity. kubelet continues using a service principal until you upgrade your agentpool. You can use the az aks nodepool upgrade --resource-group myResourceGroup --cluster-name myAKSCluster --name mynodepool --node-image-only command on your nodes to update to a managed identity. A node pool upgrade causes downtime for your AKS cluster as the nodes in the node pools are cordoned/drained and reimaged.

Note

Keep the following information in mind when updating your cluster:

  • An update only works if there's a VHD update to consume. If you're running the latest VHD, you need to wait until the next VHD is available in order to perform the update.

  • The Azure CLI ensures your addon's permission is correctly set after migrating. If you're not using the Azure CLI to perform the migrating operation, you need to handle the addon identity's permission by yourself. For an example using an Azure Resource Manager (ARM) template, see Assign Azure roles using ARM templates.

  • If your cluster was using --attach-acr to pull from images from Azure Container Registry, you need to run the az aks update --resource-group myResourceGroup --name myAKSCluster --attach-acr <ACR resource ID> command after updating your cluster to let the newly-created kubelet used for managed identity get the permission to pull from ACR. Otherwise, you won't be able to pull from ACR after the update.

Add role assignment for managed identity

When you create and use your own VNet, attach Azure disks, static IP address, route table, or user-assigned kubelet identity where the resources are outside of the worker node resource group, the Azure CLI adds the role assignment automatically. If you're using an ARM template or another method, you need to use the Principal ID of the cluster managed identity to perform a role assignment.

If you're not using the Azure CLI, but you're using your own VNet, attach Azure disks, static IP address, route table, or user-assigned kubelet identity that's outside of the worker node resource group, we recommend using user-assigned managed identity for the control plane. For the control plane to use a system-assigned managed identity, we can't get the identity ID before creating cluster, which delays the role assignment from taking effect.

Get the principal ID of managed identity

  • Get the existing identity's principal ID using the az identity show command.

    az identity show --ids <identity-resource-id>
    

    Your output should resemble the following example output:

    {
      "clientId": "<client-id>",
      "id": "/subscriptions/<subscriptionid>/resourcegroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity",
      "location": "eastus",
      "name": "myIdentity",
      "principalId": "<principal-id>",
      "resourceGroup": "myResourceGroup",
      "tags": {},
      "tenantId": "<tenant-id>",
      "type": "Microsoft.ManagedIdentity/userAssignedIdentities"
    }
    

Add role assignment

For a VNet, attached Azure disk, static IP address, or route table outside the default worker node resource group, you need to assign the Contributor role on the custom resource group.

  • Assign the Contributor role on the custom resource group using the az role assignment create command.

    az role assignment create --assignee <control-plane-identity-principal-id> --role "Contributor" --scope "<custom-resource-group-resource-id>"
    

For a user-assigned kubelet identity outside the default worker node resource group, you need to assign the Managed Identity Operator role on the kubelet identity for control plane managed identity.

  • Assign the Managed Identity Operator role on the kubelet identity using the az role assignment create command.

    az role assignment create --assignee  <control-plane-identity-principal-id> --role "Managed Identity Operator" --scope "<kubelet-identity-resource-id>"
    

Note

It may take up to 60 minutes for the permissions granted to your cluster's managed identity to populate.

Bring your own managed identity

Create a cluster using user-assigned managed identity

A custom user-assigned managed identity for the control plane enables access to the existing identity prior to cluster creation. This feature enables scenarios such as using a custom VNet or outboundType of UDR with a pre-created managed identity.

Note

USDOD Central, USDOD East, and USGov Iowa regions in Azure US Government cloud aren't supported.

AKS creates a user-assigned kubelet identity in the node resource group if you don't specify your own kubelet managed identity.

  • If you don't have a managed identity, create one using the az identity create command.

    az identity create --name myIdentity --resource-group myResourceGroup
    

    Your output should resemble the following example output:

    {                                  
      "clientId": "<client-id>",
      "clientSecretUrl": "<clientSecretUrl>",
      "id": "/subscriptions/<subscriptionid>/resourcegroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity", 
      "location": "westus2",
      "name": "myIdentity",
      "principalId": "<principal-id>",
      "resourceGroup": "myResourceGroup",                       
      "tags": {},
      "tenantId": "<tenant-id>",
      "type": "Microsoft.ManagedIdentity/userAssignedIdentities"
    }
    

Note

It may take up to 60 minutes for the permissions granted to your cluster's managed identity to populate.

  • Before creating the cluster, add the role assignment for managed identity using the az role assignment create command.

  • Create the cluster with user-assigned managed identity.

    az aks create \
        --resource-group myResourceGroup \
        --name myManagedCluster \
        --network-plugin azure \
        --vnet-subnet-id <subnet-id> \
        --dns-service-ip 10.2.0.10 \
        --service-cidr 10.2.0.0/24 \
        --enable-managed-identity \
        --assign-identity <identity-resource-id>
    

Update managed identity on an existing cluster

Note

Migrating a managed identity for the control plane, from system-assigned to user-assigned, doesn't cause any downtime for control plane and agent pools. Meanwhile, control plane components keep using the old system-assigned identity for several hours until the next token refresh.

  • If you don't have a managed identity, create one using the az identity create command.

    az identity create --name myIdentity --resource-group myResourceGroup
    

    Your output should resemble the following example output:

    {                                  
      "clientId": "<client-id>",
      "clientSecretUrl": "<clientSecretUrl>",
      "id": "/subscriptions/<subscriptionid>/resourcegroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity", 
      "location": "westus2",
      "name": "myIdentity",
      "principalId": "<principal-id>",
      "resourceGroup": "myResourceGroup",                       
      "tags": {},
      "tenantId": "<tenant-id>",
      "type": "Microsoft.ManagedIdentity/userAssignedIdentities"
    }
    
  • After creating the custom user-assigned managed identity for the control plane, add the role assignment for the managed identity using the az role assignment create command.

  • Update your cluster with your existing identities using the az aks update command. Make sure to provide the resource ID of the managed identity for the control plane by including the assign-identity argument.

    az aks update \
        --resource-group myResourceGroup \
        --name myManagedCluster \
        --enable-managed-identity \
        --assign-identity <identity-resource-id> 
    

    Your output for a successful cluster update using your own kubelet managed identity should resemble the following example output:

      "identity": {
        "principalId": null,
        "tenantId": null,
        "type": "UserAssigned",
        "userAssignedIdentities": {
          "/subscriptions/<subscriptionid>/resourcegroups/resourcegroups/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity": {
            "clientId": "<client-id>",
            "principalId": "<principal-id>"
          }
        }
      },
    

Use a pre-created kubelet managed identity

A kubelet identity enables access to the existing identity prior to cluster creation. This feature enables scenarios such as connection to ACR with a pre-created managed identity.

Pre-created kubelet identity limitations

  • Only works with a user-assigned managed cluster.
  • The China East and China North regions in Microsoft Azure operated by 21Vianet aren't supported.

Create user-assigned managed identities

Control plane managed identity

  • If you don't have a managed identity for the control plane, create one using the az identity create.

    az identity create --name myIdentity --resource-group myResourceGroup
    

    Your output should resemble the following example output:

    {                                  
      "clientId": "<client-id>",
      "clientSecretUrl": "<clientSecretUrl>",
      "id": "/subscriptions/<subscriptionid>/resourcegroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity", 
      "location": "westus2",
      "name": "myIdentity",
      "principalId": "<principal-id>",
      "resourceGroup": "myResourceGroup",                       
      "tags": {},
      "tenantId": "<tenant-id>",
      "type": "Microsoft.ManagedIdentity/userAssignedIdentities"
    }
    

kubelet managed identity

  • If you don't have a kubelet managed identity, create one using the az identity create command.

    az identity create --name myKubeletIdentity --resource-group myResourceGroup
    

    Your output should resemble the following example output:

    {
      "clientId": "<client-id>",
      "clientSecretUrl": "<clientSecretUrl>",
      "id": "/subscriptions/<subscriptionid>/resourcegroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myKubeletIdentity", 
      "location": "westus2",
      "name": "myKubeletIdentity",
      "principalId": "<principal-id>",
      "resourceGroup": "myResourceGroup",                       
      "tags": {},
      "tenantId": "<tenant-id>",
      "type": "Microsoft.ManagedIdentity/userAssignedIdentities"
    }
    

Create a cluster using user-assigned kubelet identity

Now you can create your AKS cluster with your existing identities. Make sure to provide the resource ID of the managed identity for the control plane by including the assign-identity argument, and the kubelet managed identity using the assign-kubelet-identity argument.

  • Create an AKS cluster with your existing identities using the az aks create command.

    az aks create \
        --resource-group myResourceGroup \
        --name myManagedCluster \
        --network-plugin azure \
        --vnet-subnet-id <subnet-id> \
        --dns-service-ip 10.2.0.10 \
        --service-cidr 10.2.0.0/24 \
        --enable-managed-identity \
        --assign-identity <identity-resource-id> \
        --assign-kubelet-identity <kubelet-identity-resource-id>
    

    A successful AKS cluster creation using your own kubelet managed identity should resemble the following example output:

      "identity": {
        "principalId": null,
        "tenantId": null,
        "type": "UserAssigned",
        "userAssignedIdentities": {
          "/subscriptions/<subscriptionid>/resourcegroups/resourcegroups/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity": {
            "clientId": "<client-id>",
            "principalId": "<principal-id>"
          }
        }
      },
      "identityProfile": {
        "kubeletidentity": {
          "clientId": "<client-id>",
          "objectId": "<object-id>",
          "resourceId": "/subscriptions/<subscriptionid>/resourcegroups/resourcegroups/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myKubeletIdentity"
        }
      },
    

Update an existing cluster using kubelet identity

Warning

Updating kubelet managed identity upgrades node pools, which causes downtime for your AKS cluster as the nodes in the node pools are cordoned/drained and reimaged.

Note

If your cluster was using --attach-acr to pull from images from Azure Container Registry, you need to run the az aks update --resource-group myResourceGroup --name myAKSCluster --attach-acr <ACR Resource ID> command after updating your cluster to let the newly-created kubelet used for managed identity get the permission to pull from ACR. Otherwise, you won't be able to pull from ACR after the upgrade.

Get the current control plane managed identity for your AKS cluster

  1. Confirm your AKS cluster is using the user-assigned managed identity using the az aks show command.

    az aks show -g <RGName> -n <ClusterName> --query "servicePrincipalProfile"
    

    If your cluster is using a managed identity, the output shows clientId with a value of msi. A cluster using a service principal shows an object ID. For example:

    {
      "clientId": "msi"
    }
    
  2. After confirming your cluster is using a managed identity, find the managed identity's resource ID using the az aks show command.

    az aks show -g <RGName> -n <ClusterName> --query "identity"
    

    For a user-assigned managed identity, your output should look similar to the following example output:

    {
      "principalId": null,
      "tenantId": null,
      "type": "UserAssigned",
      "userAssignedIdentities": <identity-resource-id>
          "clientId": "<client-id>",
          "principalId": "<principal-id>"
    },
    

Update your cluster with kubelet identity

  1. If you don't have a kubelet managed identity, create one using the az identity create command.

    az identity create --name myKubeletIdentity --resource-group myResourceGroup
    

    Your output should resemble the following example output:

    {
      "clientId": "<client-id>",
      "clientSecretUrl": "<clientSecretUrl>",
      "id": "/subscriptions/<subscriptionid>/resourcegroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myKubeletIdentity",
      "location": "westus2",
      "name": "myKubeletIdentity",
      "principalId": "<principal-id>",
      "resourceGroup": "myResourceGroup",                       
      "tags": {},
      "tenantId": "<tenant-id>",
      "type": "Microsoft.ManagedIdentity/userAssignedIdentities"
    }
    
  2. Update your cluster with your existing identities using the az aks update command. Make sure to provide the resource ID of the managed identity for the control plane by including the assign-identity argument, and the kubelet managed identity for assign-kubelet-identity argument.

    az aks update \
        --resource-group myResourceGroup \
        --name myManagedCluster \
        --enable-managed-identity \
        --assign-identity <identity-resource-id> \
        --assign-kubelet-identity <kubelet-identity-resource-id>
    

    Your output for a successful cluster update using your own kubelet managed identity should resemble the following example output:

      "identity": {
        "principalId": null,
        "tenantId": null,
        "type": "UserAssigned",
        "userAssignedIdentities": {
          "/subscriptions/<subscriptionid>/resourcegroups/resourcegroups/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity": {
            "clientId": "<client-id>",
            "principalId": "<principal-id>"
          }
        }
      },
      "identityProfile": {
        "kubeletidentity": {
          "clientId": "<client-id>",
          "objectId": "<object-id>",
          "resourceId": "/subscriptions/<subscriptionid>/resourcegroups/resourcegroups/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myKubeletIdentity"
        }
      },
    

Next steps

  • Use Azure Resource Manager templates to create a managed identity-enabled cluster.
  • Learn how to [use kubelogin][kubelogin-authentication] for all supported Microsoft Entra authentication methods in AKS.