ARM template for AKS cluster with managed identity and managed Azure AD integration

Evgeny Borzenin · August 5, 2020

Recently I was working with my sandbox infrastructure environment and decided to switch my AKS cluster to use Managed Identity and managed Azure AD integration. I mainly use ARM templates to describe my infrastructure and I actually didn’t find any ARM template samples showing how to configure AKS with neither managed identity, nor managed Azure AD integration, so I decided to share what I finally came up with as a solution…

Here are my AKS cluster configuration requirements:

  • AKS is deployed to iac-aks-blue|green-rg resource group
  • AKS is called iac-blue|green-aks
  • AKS is deployed to aks-net subnet of iac-aks-blue|green-vnet private virtual network
  • AKS uses advanced networking
  • AKS uses Calico networking policies
  • AKS uses pre-provisioned egress public IP address called iac-aks-blue|green-egrees-pip (also part of the ARM templates)
  • AKS uses managed identity
  • AKS uses iac-admin Azure AD group for managed Azure AD integration

AKS Managed Identity and role assignment

For resources outside of the AKS “managed” MC_* resource group, AKS managed identity needs to be granted with required permissions, so AKS is able to interact with “external” resources (for example, read/write on subnets or provision static IP address etc.). AKS managed identity has to be assigned with NetworkContributor role at the AKS subnet scope. To perform a role assignment, use the principalId of the cluster System Assigned managed identity. Here is an example how you can assign NetworkContributor role (you can find role GUID in Azure built-in roles list) for AKS managed identity with ARM template.

    "type": "Microsoft.Network/virtualNetworks/subnets/providers/roleAssignments",
    "apiVersion": "2017-05-01",
    "name": "[concat(parameters('vnetName'), '/', parameters('subnetName'), '/Microsoft.Authorization/', guid(resourceGroup().id, 'akstovnet'))]",
    "properties": {
        "roleDefinitionId": "[variables('networkContributorRole')]",
        "principalId": "[reference(resourceId('Microsoft.ContainerService/managedClusters/', parameters('clusterName')), '2020-06-01', 'Full').identity.principalId]",
        "scope": "[variables('subnetId')]"

To enable system-assigned managed identity, add the identity property at the same level as the “type”: “Microsoft.ContainerService/managedClusters” property. Use the following syntax:

"identity": {
    "type": "SystemAssigned"

and then set clientId field of servicePrincipalProfile property to msi

"servicePrincipalProfile": {
    "clientId": "msi"

Azure AD integration

AKS-managed Azure AD integration is designed to simplify the Azure AD integration experience, where users were previously required to create a client app, a server app, and required the Azure AD tenant to grant Directory Read permissions. In the new version, the AKS resource provider manages the client and server apps for you.

To enable Azure AD integration, add the aadProfile property inside properties section and use the following syntax:

"aadProfile": {
    "managed": true,
    "tenantId": "[parameters('tenantId')]",
    "adminGroupObjectIDs": [

To find your Azure AD group id by name, use the following command:

az ad group show -g 'iac-admin' --query objectId


The solution shown above works only when I set apiVersion of Microsoft.ContainerService/managedClusters to 2020-06-01 (and you actually get this version if you create your cluster with az cli or from portal and then export AKS template), but I didn’t find this version in the “official” Microsoft.ContainerService managedClusters template reference.

Final version

Here is the complete version of my ARM template.

If you have any issues/comments/suggestions related to this post, you can reach out to me at

With that - thanks for reading!