Azure Key Vault 访问策略和托管身份(ARM 模板)

Azure Key Vault access policies and Managed Identities (ARM templates)

寻求专家帮助。

我已经创建了部署 Azure 应用程序网关和 Key Vault 实例的 ARM 模板。我想在 Key Vault 中提供 App Gateway 的 principalID(用户分配的托管标识)以获取证书或机密,但失败并出现错误:

"部署模板验证失败:'第'1'行和'21178'列的模板资源'kv-project-dev/add'无效:语言表达式属性'principalId' 无法评估。请参阅 https://aka.ms/arm-template-expressions 了解使用详情。"

如果我在parameters.json[中添加用户管理身份的principalID值,它工作正常 手动文件(作为 objectID),但是,我正在寻找如何自动化这部分并在 ARM 模板部署期间自动在 Key Vault 访问策略中添加 principalID

parameters.json 文件中的这一行似乎有问题:

"objectId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('appgw-managed-id')).principalId)]"

以下资源用于创建 ARM 模板: New way to reference managed identity in ARM template and App Gateway v2 deployment with Key Vault

Parameters.json 文件查找访问策略:

"kv-servicePrincipalObjects": {
  "value": [
    {
    "tenantId": "[subscription().tenantid]",
    "objectId": "xxxx-xxxx-xxxx-xxxx-xxxx",
    "permissions": {
        "keys": [],
        "secrets": ["get","list"],
        "certificates": []
    },
    "applicationId": ""
    },
    {
      "tenantId": "[subscription().tenantid]",
      "objectId": "yyyy-yyyy-yyyy-yyyy-yyyy",
      "permissions": {
          "keys": ["all"],
          "secrets": ["all"],
          "certificates": ["all"]
      },
      "applicationId": ""
    },
    {
      "tenantId": "[subscription().tenantid]",
      "objectId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('appgw-managed-id')).principalId)]",
      "permissions": {
          "keys": [],
          "secrets": ["get"],
          "certificates": ["get"]
      },
      "applicationId": ""
    }
  ]
},

Template.json 文件以创建 Key Vault 并分配访问策略:

{
        "type": "Microsoft.KeyVault/vaults",
        "apiVersion": "2019-09-01",
        "name": "[variables('kv-name')]",
        "location": "[parameters('location')]",
        "tags": "[parameters('resource-Tags')]",
        "dependsOn": [
            "[resourceId('Microsoft.Network/virtualNetworks', variables('vnet-name'))]",
            "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('appgw-managed-id'))]"
        ],
         "properties": {
            "enabledForDeployment": "[parameters('kv-enabledForDeployment')]",
            "enabledForTemplateDeployment": "[parameters('kv-enabledForTemplateDeployment')]",
            "enabledForDiskEncryption": "[parameters('kv-enabledForDiskEncryption')]",
            "enableRbacAuthorization": "[parameters('kv-enableRbacAuthorization')]",
            "accessPolicies": [],
            "tenantId": "[parameters('tenant')]",
            "sku": {
                "name": "[parameters('kv-sku')]",
                "family": "A"
            },
            "enableSoftDelete": "[parameters('kv-enableSoftDelete')]",
            "softDeleteRetentionInDays": "[parameters('kv-softDeleteRetentionInDays')]",
            "enablePurgeProtection": "[parameters('kv-enablePurgeProtection')]",
            "KVvirtualNetworkConfiguration": {
                "KVsubnetResourceId": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnet-name'), 'kv-subnet')]"
            },
            "networkAcls": {
                "defaultAction": "Deny",
                "bypass": "AzureServices",
                "virtualNetworkRules": [
                {
                    "id": "[concat(parameters('kv-virtualNetworks'), '/subnets/','kv-subnet')]",
                    "ignoreMissingVnetServiceEndpoint": false
                }
                ],
                "ipRules": "[parameters('kv-ipRules')]"
            }
        }
    },
{
        "type": "Microsoft.KeyVault/vaults/accessPolicies",
        "name": "[concat(variables('kv-name'), '/add')]",
        "apiVersion": "2019-09-01",
            "dependsOn": [
                "[resourceId('Microsoft.KeyVault/vaults', variables('kv-name'))]"
            ],
        "properties": {
            "copy": [
            {
                "name": "accessPolicies",
                "count": "[length(parameters('kv-servicePrincipalObjects'))]",
                "input": {
                    "tenantId": "[parameters('kv-servicePrincipalObjects')[copyIndex('accessPolicies')].tenantId]",
                    "objectId": "[parameters('kv-servicePrincipalObjects')[copyIndex('accessPolicies')].objectId]",
                    "permissions": {
                        "keys": "[parameters('kv-servicePrincipalObjects')[copyIndex('accessPolicies')].permissions.keys]",
                        "secrets": "[parameters('kv-servicePrincipalObjects')[copyIndex('accessPolicies')].permissions.secrets]",
                        "certificates": "[parameters('kv-servicePrincipalObjects')[copyIndex('accessPolicies')].permissions.certificates]"
                    },
                    "applicationId": "[parameters('kv-servicePrincipalObjects')[copyIndex('accessPolicies')].applicationId]"
                }
            }
            ]
        }
    }

这行有错别字:

"objectId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('appgw-managed-id')).principalId)]"

应该是:

"objectId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('appgw-managed-id'))).principalId]"

请注意,我们将右括号移到了最后。 该行试图从 resourceId() 的结果中获取 principalId 属性,当它需要从 reference() 返回的对象中获取它时。