Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Azure Kubernetes Service (AKS) clusters require either a Microsoft Entra service principal or a managed identity to dynamically create and manage other Azure resources. This article describes how to create a Microsoft Entra service principal and use it with your AKS cluster.
Note
For optimal security and ease of use, we recommend using managed identities instead of service principals to authorize access from an AKS cluster to other resources in Azure. A managed identity is a special type of service principal that you can use to get Microsoft Entra credentials without the need to manage and secure credentials. For more information, see Use a managed identity in AKS.
Prerequisites
- You need Azure CLI version 2.0.59 or higher. Find your version using the
az --versioncommand. If you need to install or upgrade, see Install Azure CLI.
- If using Azure PowerShell, you need Azure PowerShell version 5.0.0 or higher. Find your version using the
Get-InstalledModule -Name Azcmdlet. If you need to install or upgrade, see Install the Azure Az PowerShell module.
- You need permissions to register an application with your Microsoft Entra tenant and to assign the application to a role in your subscription. If you don't have the necessary permissions, you need to ask your Microsoft Entra ID or subscription administrator to assign the necessary permissions or create the service principal for you.
Considerations when using a service principal
Keep the following considerations in mind when using a Microsoft Entra service principal with AKS:
- The service principal for Kubernetes is a part of the cluster configuration, but don't use this identity to deploy the cluster. Instead, create a service principal first, then use that service principal to create the AKS cluster.
- Every service principal is associated with a Microsoft Entra application. You can associate the service principal for a Kubernetes cluster with any valid Microsoft Entra application name (for example:
https://www.contoso.org/example). The URL for the application doesn't have to be a real endpoint. - When you specify the service principal client ID, use the value of the application ID (
appIdfor Azure CLI orApplicationIdfor Azure PowerShell). - On the agent node virtual machines (VMs) in the AKS cluster, the service principal credentials are stored in the
/etc/kubernetes/azure.jsonfile. - When you delete an AKS cluster that you created using the
az aks createcommand or theNew-AzAksClustercmdlet, the service principal created isn't automatically deleted. See the steps to delete a service principal. - If you're using a service principal from a different Microsoft Entra tenant, there are other considerations around the permissions available when you deploy the cluster. You might not have the appropriate permissions to read and write directory information. For more information, see What are the default user permissions in Microsoft Entra ID?
Create a service principal
Create a service principal using the
az ad sp create-for-rbaccommand.# Set environment variable SERVICE_PRINCIPAL_NAME=<your-service-principal-name> # Create the service principal az ad sp create-for-rbac --name $SERVICE_PRINCIPAL_NAMEYour output should be similar to the following example output:
{ "appId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "displayName": "myAKSClusterServicePrincipal", "name": "http://myAKSClusterServicePrincipal", "password": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }Copy the values for
appIdandpasswordfrom the output to use when creating the AKS cluster.
Create a service principal using the
New-AzADServicePrincipalcommand.# Set environment variable $SpName = <your-service-principal-name> # Create the service principal New-AzADServicePrincipal -DisplayName $SpName -OutVariable spYour output should be similar to the following example output:
Secret : System.Security.SecureString ServicePrincipalNames : {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, http://myAKSClusterServicePrincipal} ApplicationId : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ObjectType : ServicePrincipal DisplayName : myAKSClusterServicePrincipal Id : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Type :The values are stored in a variable that you use when creating the AKS cluster.
Decrypt the value stored in the Secret secure string using the following command.
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($sp.Secret) [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
Create an AKS cluster with an existing service principal
Create an AKS cluster with an existing service principal using the
az aks createcommand with the--service-principaland--client-secretparameters set to specify theappIdandpasswordvalues.# Set environment variables RESOURCE_GROUP=<your-resource-group-name> CLUSTER_NAME=<your-aks-cluster-name> APP_ID=<app-id> CLIENT_SECRET=<password-value> # Create the AKS cluster az aks create \ --resource-group $RESOURCE_GROUP \ --name $CLUSTER_NAME \ --service-principal $APP_ID \ --client-secret $CLIENT_SECRET \ --generate-ssh-keys
Convert the service principal
ApplicationIdandSecretto a PSCredential object using the following command.$Cred = New-Object -TypeName System.Management.Automation.PSCredential ($sp.ApplicationId, $sp.Secret)Create an AKS cluster with an existing service principal using the
New-AzAksClustercmdlet and specify theServicePrincipalIdAndSecretparameter with the PSCredential object as its value.# Set environment variables $ResourceGroupName = <your-resource-group-name> $ClusterName = <your-aks-cluster-name> # Create the AKS cluster New-AzAksCluster -ResourceGroupName $ResourceGroupName -Name $ClusterName -ServicePrincipalIdAndSecret $Cred
Note
If you're using an existing service principal with customized secret, make sure the secret isn't longer than 190 bytes.
Delegate access to other Azure resources
You can use the service principal for the AKS cluster to access other resources. For example, if you want to deploy your AKS cluster into an existing Azure virtual network (VNet) subnet, connect to ACR, or access keys or secrets in a key vault from your cluster, then you need to delegate access to those resources to the service principal. To delegate access, assign an Azure role-based access control (Azure RBAC) role to the service principal.
When you assign roles, you specify the scope for the role assignment, such as a resource group or VNet resource. The role assignment determines what permissions the service principal has on the resource and at what scope.
Important
Permissions granted to a service principal associated with a cluster can take up 60 minutes to propagate.
Create a role assignment
Note
The scope for a resource needs to be a full resource ID, such as /subscriptions/\<guid\>/resourceGroups/myResourceGroup or /subscriptions/\<guid\>/resourceGroups/myResourceGroupVnet/providers/Microsoft.Network/virtualNetworks/myVnet.
Create a role assignment using the
az role assignment createcommand. Specify the value of the service principal app ID for the--assigneeparameter and the scope for the role assignment for the--scopeparameter. The following example assigns the service principal permissions to access secrets in a key vault:az role assignment create \ --assignee <app-id> \ --scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.KeyVault/vaults/<vault-name>" \ --role "Key Vault Secrets User"
Create a role assignment using the
New-AzRoleAssignmentcmdlet. Specify the value of the service principal app ID for the-ApplicationIdparameter and the scope for the role assignment for the-Scopeparameter. The following example assigns the service principal permissions to access secrets in a key vault:New-AzRoleAssignment -ApplicationId <app-id> ` -Scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.KeyVault/vaults/<vault-name>" ` -RoleDefinitionName "Key Vault Secrets User"
Grant access to Azure Container Registry
If you use Azure Container Registry (ACR) as your container image store, you need to grant permissions to the service principal for your AKS cluster to read and pull images. We recommend following the steps in Authenticate with Azure Container Registry from Azure Kubernetes Service to integrate with a registry and assign the appropriate role for the service principal.
Grant access to networking resources
If you're using advanced networking with a VNet and subnet or public IP addresses in different resource group, you can assign the Network Contributor built-in role on the subnet within the VNet. Alternatively, you can create a custom role with permissions to access the network resources in that resource group. For more information, see AKS service permissions.
Grant access to storage disks
If you need to access existing disk resources in another resource group, assign one of the following sets of role permissions:
- Create a custom role and define the Microsoft.Compute/disks/read and Microsoft.Compute/disks/write role permissions.
- Assign the Virtual Machine Contributor built-in role on the resource group.
Grant access to Azure Container Instances
If you use virtual kubelet to integrate with AKS and run Azure Container Instances (ACI) in resource group separate from the AKS cluster, you need to assign Contributor permissions to the AKS cluster service principal for the ACI resource group.
Delete a service principal
Query for the service principal client ID (
servicePrincipalProfile.clientId) and delete the service principal using theaz ad sp deletecommand with the--idparameter. The [az aks show][az-aks-show] command retrieves the client ID for the specified AKS cluster.# Set environment variables RESOURCE_GROUP=<your-resource-group-name> CLUSTER_NAME=<your-aks-cluster-name> # Delete the service principal az ad sp delete --id $(az aks show \ --resource-group $RESOURCE_GROUP \ --name $CLUSTER_NAME \ --query servicePrincipalProfile.clientId \ --output tsv)
Query for the service principal client ID (
ServicePrincipalProfile.ClientId) and delete the service principal using theRemove-AzADServicePrincipalcmdlet with the-ApplicationIdparameter. The [Get-AzAksCluster][get-azakscluster] cmdlet retrieves the client ID for the specified AKS cluster.# Set environment variables $ResourceGroupName = <your-resource-group-name> $ClusterName = <your-aks-cluster-name> $ClientId = (Get-AzAksCluster -ResourceGroupName myResourceGroup -Name myAKSCluster ).ServicePrincipalProfile.ClientId # Delete the service principal Remove-AzADServicePrincipal -ApplicationId $ClientId
Resolve service principal credential issues
Azure CLI caches the service principal credentials for AKS clusters.
Azure PowerShell caches the service principal credentials for AKS clusters.
If these credentials expire, you might encounter errors during AKS cluster deployment. If there's an issue with the cached credentials, you might receive an error message similar to the following error message:
Operation failed with status: 'Bad Request'.
Details: The credentials in ServicePrincipalProfile were invalid. Please see https://aka.ms/aks-sp-help for more details.
Details: adal: Refresh request failed. Status Code = '401'.
You can check the expiration date of your service principal credentials using the az ad app credential list command with the "[].endDateTime" query. The output shows you the endDateTime of your credentials.
az ad app credential list \
--id <app-id> \
--query "[].endDateTime" \
--output tsv
- Check the expiration date of your service principal credentials using the
Get-AzADAppCredentialcmdlet. The output shows you theEndDateof your credentials.
Get-AzADAppCredential -ApplicationId <app-id>
The default expiration time for the service principal credentials is one year. If your credentials are older than one year, you can reset the existing credentials or create a new service principal.