How to create user-assigned managed identity, Key Vault, assign access policy using ARM template

There is already a plenty of materials about managed identities in Azure. But how to create a user-assigned managed identity and grant it the access to a key vault using an ARM template? I tried to find any references but to no avail.

First you’ll need a user-assigned managed identity:

{
  "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "identityName": {
      "type": "string"
    }
  },
  "variables": {
    "idApiVersion": "[providers('Microsoft.ManagedIdentity', 'userAssignedIdentities').apiVersions[0]]",
    "location": "[resourceGroup().location]"
  },
  "resources": [
    {
      "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
      "apiVersion": "[variables('idApiVersion')]",
      "name": "[parameters('identityName')]",
      "location": "[variables('location')]"
    }
  ]
}

Then a key vault:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "kvName": {
      "type": "string"
    }
    "identityName": {
      "type": "string"
    }
  },
  "variables": {
    "kvApiVersion": "[providers('Microsoft.KeyVault', 'vaults').apiVersions[0]]",
    "location": "[resourceGroup().location]",
    "tenantId": "[subscription().tenantId]"
  },
  "resources": [
    {
      "type": "Microsoft.KeyVault/vaults",
      "apiVersion": "[variables('kvApiVersion')]",
      "name": "[parameters('kvName')]",
      "location": "[variables('location')]",
      "properties": {
        "sku": {
          "family": "A",
          "name": "standard"
        },
        "tenantId": "[variables('tenantId')]",
        "enableSoftDelete": true,
        "enabledForDeployment": true,
        "enabledForTemplateDeployment": true,
        "enabledForDiskEncryption": false,
        "accessPolicies": [
          {
            "tenantId": "[variables('tenantId')]",
            "objectId": "[reference(concat('Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('identityName')), variables('idApiVersion')).principalId]",
            "permissions": {
              "keys": [
                "Get",
                "List"
              ],
              "secrets": [
                "Get",
                "List"
              ],
              "certificates": [
                "Get",
                "List"
              ]
            }
          }
        ]
      }
    }
  ]
}

Voila! The identity has full read-only access to all secrets in the vault.

Due to the limitations of ARM, function reference() cannot be placed inside variables. It’s a runtime function so must be placed inside resources. What in the case of key vault’s access policies limits the options for composition (real programming using ARM) and unnecessarily complicates the template. For example, it’s hard to have an if with two variables. Otherwise, it’s quite simple and straightforward.

This entry was posted in Infrastructure and tagged , . Bookmark the permalink.

2 Responses to How to create user-assigned managed identity, Key Vault, assign access policy using ARM template

  1. Pingback: How to combine Key Vault access policy for AAD application and user-assigned managed identity in single ARM template | Alexander Batishchev's Blog

  2. Kamil says:

    Thank you! I’ve just used it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.