4

I'm having trouble referencing a user assigned identity that I create alongside a KeyVault instance within the same template. I've searched through documentation on how to reference managed identities in general and I believe it looks like the following:

reference(resourceId('resource-type', 'resource-name'), 'api-version', 'Full)).identity.principalId

However, this doesn't work for me and I'm not sure if it has something to do with deploying my templates at the subscription scope. I'm currently using linkedTemplates so that I can organize my code better and have a main template like the following:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.1",
  "parameters": {},
  "resources": [
    {
      "apiVersion": "2020-06-01",
      "location": "[variables('location')]", 
      "name": "key-vault-test”,
      "properties": {
        "mode": "Incremental",
         "parameters": { },
         "templateLink": {
           "relativePath": “vault.json"
         }
      },
      "type": "Microsoft.Resources/deployments"
    }
  ],
}

Next, vault.json is as follows:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.1",
  "parameters": {
    …
  },
  "resources": [
    {
      "apiVersion": "2018-05-01",
      "location": “[…..]”,
      "name": "key-vault",
      "type": "Microsoft.Resources/resourceGroups"
    },
    {
      "apiVersion": "2020-06-01",
      "dependsOn": [
        "[resourceId('Microsoft.Resources/resourceGroups', 'key-vault')]"
      ],
      "name": “user-assigned-identity-dep”,
      "properties": {
        "expressionEvaluationOptions": {
          "scope": "outer"
        },
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              "apiVersion": "2018-11-30",
              "location": “[…]”,
              "name": “myIdentity”,
              "type": "Microsoft.ManagedIdentity/userAssignedIdentities"
            }
          ]
        }
      },
      "resourceGroup": "key-vault",
      "type": "Microsoft.Resources/deployments"
    },
    {
      "apiVersion": "2020-06-01",
      "name": "key-vault-dep”,
      "properties": {
        "expressionEvaluationOptions": {
          "scope": "outer"
        },
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              "apiVersion": "2018-02-14",
              "location": “[…]”,
              "name": "[concat('key-vault-', uniqueString(subscription().id))]",
              "properties": {
                "accessPolicies": [
                    {
                        "objectId": "[reference(variables('keyVaultIdentityId'), '2018-11-30', 'Full').identity.principalId]",
                        "permissions": {
                            "secrets": [
                            "get",
                            "list"
                            ]
                        },
                        "tenantId": "[subscription().tenantId]"
                    }
                ],
                "enableSoftDelete": true,
                "sku": {
                  "family": "A",
                  "name": "Standard"
                },
                "tenantId": "[subscription().tenantId]"
              },
              "type": "Microsoft.KeyVault/vaults"
            }
          ]
        }
      },
      "resourceGroup": "key-vault",
      "type": "Microsoft.Resources/deployments"
    }
  ],
  "variables": {
    "keyVaultIdentityId": "/subscriptions/…/resourceGroups/key-vault/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity”
  }
}

When I deploy the main template, the reference function that I've crafted returns me the deployment of the keyVault and not the managed identity at all.

'The language expression property 'identity' doesn't exist, available properties are 'apiVersion, location, tags, properties, deploymentResourceLineInfo, subscriptionId, resourceGroupName, scope, resourceId, referenceApiVersion, condition, isConditionTrue, isTemplateResource, isAction, provisioningOperation

I'm not sure if I'm doing something wrong or if there's a better way to do this. In summary, I'm attempting to create a user assigned identity and create a key vault with access policies for that identity in the same template.

corgc0der
  • 43
  • 1
  • 4

2 Answers2

6

I got the same error but I had forgotten to assign a managed identity to my resource in the ARM template like:

"identity": {
    "type": "SystemAssigned"
  },

Example:

{
      "type": "Microsoft.Web/sites",
      "kind": "functionapp",
      "name": "[variables('uniqueResourceNameBase')]",
      "apiVersion": "2016-08-01",
      "location": "[resourceGroup().location]",
      "identity": {
        "type": "SystemAssigned"
      },
      "properties": { ... }
}

After doing this I could use .identity.principalId.

Source:

https://www.codeisahighway.com/there-is-a-new-way-to-reference-managed-identity-in-arm-template/

You can also manually set it in Azure Portal under your service -> Identity.

A system assigned managed identity is restricted to one per resource and is tied to the lifecycle of this resource. You can grant permissions to the managed identity by using Azure role-based access control (Azure RBAC). The managed identity is authenticated with Azure AD, so you don’t have to store any credentials in code. Learn more about Managed identities.

enter image description here

Ogglas
  • 62,132
  • 37
  • 328
  • 418
5

If you want to get the principalId of the user assigned identity, you need to use the following expression. For more details, please refer to here

[reference(resourceId('<subscriptionId>','<resourceGroupName>','Microsoft.ManagedIdentity/userAssignedIdentities', parameters('name')),'2018-11-30','Full').properties.principalId]

for example my template

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "name": {
            "defaultValue": "mytest",
            "type": "String"
        }
    },
    "variables": {},
    "resources": [{
            "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
            "name": "[parameters('name')]",
            "apiVersion": "2018-11-30",
            "location": "[resourceGroup().location]"
        }

    ],
    "outputs": {
        "principalId": {
            "value": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('name')),'2018-11-30','Full').properties.principalId]",
            "type": "string"
        }
    }
}

enter image description here

Jim Xu
  • 21,610
  • 2
  • 19
  • 39
  • If it is useful for you, could you please [accept it as an answer](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)? – Jim Xu Nov 12 '20 at 07:28
  • 3
    You have no idea how long I've spent on getting this right. Using `properties.principalId` did the trick for me. For some reason `identity.principalId` did not work even though the docs told me to use it. Thank you so much! – corgc0der Nov 12 '20 at 13:31