Use a managed identity in Azure Kubernetes Service (AKS)

Azure Kubernetes Service (AKS) clusters require a Microsoft Entra identity to access Azure resources like load balancers and managed disks. Managed identities for Azure resources are the recommended way to authorize access from an AKS cluster to other Azure services.

You can use a managed identity to authorize access from an AKS cluster to any service that supports Microsoft Entra authorization, without needing to manage credentials or include them in your code. You assign to the managed identity an Azure role-based access control (Azure RBAC) role to grant it permissions to a particular resource in Azure. For example, you can grant permissions to a managed identity to access secrets in an Azure key vault for use by the cluster. For more information about Azure RBAC, see What is Azure role-based access control (Azure RBAC)?.

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

  • System-assigned managed identity. A system-assigned managed identity is associated with a single Azure resource, such as an AKS cluster. It exists for the lifecycle of the cluster only.
  • User-assigned managed identity. A user-assigned managed identity is a standalone Azure resource that an AKS cluster can use to authorize access to other Azure services. It persists separately from the AKS cluster and can be used by multiple Azure resources.
  • Pre-created kubelet managed identity. A pre-created kubelet managed identity is an optional user-assigned identity that kubelet can use to access other resources in Azure. If you don't specify a user-assigned managed identity for kubelet, AKS creates a system-assigned kubelet identity in the node resource group.

To learn more about managed identities, see Managed identities for Azure resources.

Overview

An AKS cluster uses a managed identity to request tokens from Microsoft Entra. These tokens are used to authorize access to other resources running in Azure. You can assign an Azure RBAC role to a managed identity to grant your cluster permissions to access specific resources. For example, if your cluster needs to access secrets in an Azure key vault, you can assign to the cluster's managed identity an Azure RBAC role that grants those permissions.

A managed identity can be either system-assigned or user-assigned. These two types of managed identities are similar in that you can use either type to authorize access to Azure resources from your AKS cluster. The key difference between them is that a system-assigned managed identity is associated with a single Azure resource like an AKS cluster, while a user-assigned managed identity is itself a standalone Azure resource. For more details on the differences between types of managed identities, see Managed identity types in Managed identities for Azure resources.

Both types of managed identities are managed by the Azure platform, so that you can authorize access from your applications without needing to provision or rotate any secrets. Azure manages the identity's credentials for you.

When you deploy an AKS cluster, a system-assigned managed identity is created for you by default. You can also create the cluster with a user-assigned managed identity.

It's also possible to create a cluster with an application service principal rather that a managed identity. Managed identities are recommended over service principals for security and ease of use. For more information about creating a cluster with a service principal, see Use a service principal with Azure Kubernetes Service (AKS).

You can update an existing cluster to use a managed identity from an application service principal. You can also update an existing cluster to a different type of managed identity. If your cluster is already using a managed identity and the identity was changed, for example if you updated the cluster identity type from system-assigned to user-assigned, then there is a delay while control plane components switch to the new identity. Control plane components continue to use the old identity until its token expires. After the token is refreshed, they switch to the new identity. This process can take several hours.

The system-assigned and user-assigned identity types differ from a Microsoft Entra Workload identity, which is intended for use by an application running on a pod.

Before you begin

Before running the examples in this article, set your subscription as the current active subscription by calling the az account set command and passing in your subscription ID.

az account set --subscription <subscription-id>

Also create an Azure resource group if you don't already have one by calling the az group create command.

az group create \
    --name myResourceGroup \
    --location chinanorth3

Enable a system-assigned managed identity

A system-assigned managed identity is an identity that is associated with an AKS cluster or another Azure resource. The system-assigned managed identity is tied to the lifecycle of the cluster. When the cluster is deleted, the system-assigned managed identity is also deleted.

The AKS cluster can use the system-assigned managed identity to authorize access to other resources running in Azure. You can assign an Azure RBAC role to the system-assigned managed identity to grant the cluster permissions to access specific resources. For example, if your cluster needs to access secrets in an Azure key vault, you can assign to the system-assigned managed identity an Azure RBAC role that grants those permissions.

Enable a system-assigned managed identity on a new AKS cluster

To enable a system-assigned managed identity on a new cluster, call the az aks create. A system-assigned managed identity is enabled on the new cluster by default.

Create an AKS cluster using the az aks create command.

az aks create \
    --resource-group myResourceGroup \
    --name myManagedCluster \
    --generate-ssh-keys

To verify that a system-assigned managed identity is enabled for the cluster after it has been created, see Determine which type of managed identity a cluster is using.

Update an existing AKS cluster to use a system-assigned managed identity

To update an existing AKS cluster that is using a service principal to use a system-assigned managed identity instead, run the az aks update command with the --enable-managed-identity parameter.

az aks update \
    --resource-group myResourceGroup \
    --name myManagedCluster \
    --enable-managed-identity

After you update the cluster to use a system-assigned managed identity instead of a service principal, the control plane and pods use the system-assigned managed identity for authorization when accessing other services in Azure. Kubelet continues using a service principal until you also 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 re-imaged.

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 (ACR), 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 a role assignment for a system-assigned managed identity

You can assign an Azure RBAC role to the system-assigned managed identity to grant the cluster permissions on another Azure resource. Azure RBAC supports both built-in and custom role definitions that specify levels of permissions. For more information about assigning Azure RBAC roles, see Steps to assign an Azure role.

When you assign an Azure RBAC role to a managed identity, you must define the scope for the role. In general, it's a best practice to limit the scope of a role to the minimum privileges required by the managed identity. For more information on scoping Azure RBAC roles, see Understand scope for Azure RBAC.

When you create and use your own VNet, attached 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, use the principal ID of the managed identity to perform a role assignment.

If you're not using the Azure CLI, but you're using your own VNet, attached Azure disks, static IP address, route table, or user-assigned kubelet identity that's outside of the worker node resource group, we recommend using a user-assigned managed identity for the control plane. When the control plane uses a system-assigned managed identity, the identity is created at the same time as the cluster, so the role assignment can't be performed until the cluster has been created.

Get the principal ID of the system-assigned managed identity

To assign an Azure RBAC role to a cluster's system-assigned managed identity, you first need the principal ID for the managed identity. Get the principal ID for the cluster's system-assigned managed identity by calling the az aks show command.

# Get the principal ID for a system-assigned managed identity.
CLIENT_ID=$(az aks show \
    --name myAKSCluster \
    --resource-group myResourceGroup \
    --query identity.principalId \
    --output tsv)

Assign an Azure RBAC role to the system-assigned managed identity

To grant a system-assigned managed identity permissions to a resource in Azure, call the az role assignment create command to assign an Azure RBAC role to the managed identity.

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

For example, assign the Network Contributor role on the custom resource group using the az role assignment create command. For the --scope parameter, provide the resource ID for the resource group for the cluster.

az role assignment create \
    --assignee $CLIENT_ID \
    --role "Network Contributor" \
    --scope "<resource-group-id>"

Note

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

Enable a user-assigned managed identity

A user-assigned managed identity is a standalone Azure resource. When you create a cluster with a user-assigned managed identity for the control plane, the user-assigned managed identity resource must exist prior to cluster creation. This feature enables scenarios such as creating the cluster with a custom VNet or with an outbound type of user-defined routing (UDR).

Create a user-assigned managed identity

If you don't yet have a user-assigned managed identity resource, 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": "chinaeast2",
  "name": "myIdentity",
  "principalId": "<principal-id>",
  "resourceGroup": "myResourceGroup",                       
  "tags": {},
  "tenantId": "<tenant-id>",
  "type": "Microsoft.ManagedIdentity/userAssignedIdentities"
}

Get the principal ID of the user-assigned managed identity

To get the principal ID of the user-assigned managed identity, call az identity show and query on the principalId property:

CLIENT_ID=$(az identity show \
    --name myIdentity \
    --resource-group myResourceGroup \
    --query principalId \
    --output tsv)

Get the resource ID of the user-assigned managed identity

To create a cluster with a user-assigned managed identity, you will need the resource ID for the new managed identity. To get the resource ID of the user-assigned managed identity, call az aks show and query on the id property:

RESOURCE_ID=$(az identity show \
    --name myIdentity \
    --resource-group myResourceGroup \
    --query id \
    --output tsv)

Assign an Azure RBAC role to the user-assigned managed identity

Before you create the cluster, add a role assignment for the managed identity by calling the az role assignment create command.

The following example assigns the Key Vault Secrets User role to the user-assigned managed identity to grant it permissions to access secrets in a key vault. The role assignment is scoped to the key vault resource:

az role assignment create \
    --assignee $CLIENT_ID \
    --role "Key Vault Secrets User" \
    --scope "<keyvault-resource-id>"

Note

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

Create a cluster with the user-assigned managed identity

To create an AKS cluster with the user-assigned managed identity, call the az aks create command. Include the --assign-identity parameter and pass in the resource ID for the 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 \
    --assign-identity $RESOURCE_ID \
    --generate-ssh-keys

Update an existing cluster to use a user-assigned managed identity

To update an existing cluster to use a user-assigned managed identity, call the az aks update command. Include the --assign-identity parameter and pass in the resource ID for the user-assigned managed identity:

az aks update \
    --resource-group myResourceGroup \
    --name myManagedCluster \
    --enable-managed-identity \
    --assign-identity $RESOURCE_ID

The output for a successful cluster update to use a user-assigned 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>"
      }
    }
  },

Note

Migrating a managed identity for the control plane from system-assigned to user-assigned doesn't result in any downtime for control plane and agent pools. Control plane components continue to the old system-assigned identity for up to several hours, until the next token refresh.

Determine which type of managed identity a cluster is using

To determine which type of managed identity your existing AKS cluster is using, call the az aks show command and query for the identity's type property.

az aks show \
    --name myAKSCluster \
    --resource-group myResourceGroup \
    --query identity.type \
    --output tsv       

If the cluster is using a managed identity, the value of the type property will be either SystemAssigned or UserAssigned.

If the cluster is using a service principal, the value of the type property will be null. Consider upgrading your cluster to use a managed identity.

Use a pre-created kubelet managed identity

A pre-created kubelet identity is a user-assigned managed identity that exists prior to cluster creation. This feature enables scenarios such as connection to Azure Container Registry (ACR) during cluster creation.

Note

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

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": "chinaeast2",
  "name": "myKubeletIdentity",
  "principalId": "<principal-id>",
  "resourceGroup": "myResourceGroup",                       
  "tags": {},
  "tenantId": "<tenant-id>",
  "type": "Microsoft.ManagedIdentity/userAssignedIdentities"
}

Assign an RBAC role to the kubelet managed identity

Assign the Managed Identity Operator role on the kubelet identity using the az role assignment create command. Provide the kubelet identity's principal ID for the $KUBELET_CLIENT_ID variable.

az role assignment create \
    --assignee $KUBELET_CLIENT_ID \
    --role "Managed Identity Operator" \
    --scope "<kubelet-identity-resource-id>"

Create a cluster to use the 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 \
    --assign-identity <identity-resource-id> \
    --assign-kubelet-identity <kubelet-identity-resource-id> \
    --generate-ssh-keys

A successful AKS cluster creation using a kubelet managed identity should result in output similar to the following:

  "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 to use the kubelet identity

To update an existing cluster to use the kubelet managed identity, first get the current control plane managed identity for your AKS cluster.

Warning

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

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

    az aks show \
        --resource-group <RGName> \
        --name <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:

    # The cluster is using a managed identity.
    {
      "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 --resource-group <RGName> \
        --name <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>"
    },
    
  3. Update your cluster with your existing identities using the az aks update command. Provide the resource ID of the user-assigned managed identity for the control plane for the assign-identity argument. Provide the resource ID of the kubelet managed identity for the 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"
    }
  },