4

I'm trying to conditionally add Access Policies to a Key Vault and the problem is that you can't have more than 1 resource in the template with the name of KeyVault/accessPolicies/add

This is effectively what I want to achieve:

{
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "vaultName": {
            "type": "string"
        }
    },
    "resources": [
        {
            "condition": "[parameters('someCondition')]",
            "type": "Microsoft.KeyVault/vaults/accessPolicies",
            "name": "[concat(parameters('vaultName'), '/add')]",
            "apiVersion": "2016-10-01",
            "properties": {
                "accessPolicies": [
                    {
                        "tenantId": "[if(parameters('someCondition'), reference(variables('someAppServiceResourceId'), '2015-08-31-PREVIEW').tenantId, json('null'))]",
                        "objectId": "[if(parameters('someCondition'), reference(variables('someAppServiceResourceId'), '2015-08-31-PREVIEW').principalId, json('null'))]",
                        "permissions": {
                            "keys": ["all"],
                            "secrets": ["all"],
                            "certificates": ["all"],
                            "storage": ["all"]
                        }
                    }
                ]
            }
        },
        {
            "condition": "[parameters('otherCondition')]",
            "type": "Microsoft.KeyVault/vaults/accessPolicies",
            "name": "[concat(parameters('vaultName'), '/add')]",
            "apiVersion": "2016-10-01",
            "properties": {
                "accessPolicies": [
                    {
                        "tenantId": "[if(parameters('otherCondition'), reference(variables('someOTHERAppServiceResourceId'), '2015-08-31-PREVIEW').tenantId, json('null'))]",
                        "objectId": "[if(parameters('otherCondition'), reference(variables('someOTHERAppServiceResourceId'), '2015-08-31-PREVIEW').principalId, json('null'))]",
                        "permissions": {
                            "keys": ["all"],
                            "secrets": ["all"],
                            "certificates": ["all"],
                            "storage": ["all"]
                        }
                    }
                ]
            }
        }
    ],
    "outputs": {
    }
}

However I can only have one resource in this deployment by the name of 'KeyVaultName/add'.

I was thinking I could conditionally build the array of access policies in variables and do some array concatenation, but it won't work since I use the reference() function inside the access policy to go and fetch the tenant and principal ID.

David C
  • 501
  • 1
  • 4
  • 16
  • have you tried nested templates ? https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/linked-templates#nested-template – Thomas Apr 21 '20 at 08:54
  • Working on testing that approach now to see if it cures it! – David C Apr 21 '20 at 08:54
  • Did you end up finding an answer? I'm having the exact same issue now – st0ve Feb 05 '21 at 17:56
  • Don't see how nested templates would help here as the conflict is at the resource level. Actually other than the hack suggested by @14207973 there doesn't really seem to be any way to solve this. – joniba Dec 25 '22 at 10:25

2 Answers2

0

why do you think this would not work?

"properties": {
    "copy": [
        {
            "name": "accessPolicies",
            "count": "[xxx]",
            "input": {
                "tenantId": "[if(parameters('otherCondition'), reference(variables('someOTHERAppServiceResourceId'), '2015-08-31-PREVIEW').tenantId, json('null'))]",
                "objectId": "[if(parameters('otherCondition'), reference(variables('someOTHERAppServiceResourceId'), '2015-08-31-PREVIEW').principalId, json('null'))]",
                "permissions": {
                    "keys": ["all"],
                    "secrets": ["all"],
                    "certificates": ["all"],
                    "storage": ["all"]
                }
            }
        }
    ]
}
4c74356b41
  • 69,186
  • 6
  • 100
  • 141
  • I think that will fail when there are 0 items in the count, which is a scenario that will happen for us. – David C Apr 21 '20 at 09:02
  • 1
    just put a condition on the resource so that it skips this resource when the count is 0, so it would work. also I think they fixed 0 count for copies error, but I'm not sure. anyway, condition will always work – 4c74356b41 Apr 21 '20 at 09:08
  • This is so close, but unfortunately 0 count still seems to be an issue! – David C Apr 21 '20 at 12:49
  • 1
    your api-version is outdated. https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/copy-properties#copy-limits – 4c74356b41 Apr 21 '20 at 12:59
0

"accessPolicies" takes an array, which allows you to specify multiple policies through a single resource. You can have the policies within the same array applied conditionally, using if expressions similar to what you're already doing. I've found that json('null') causes deployment errors for me. Instead, when the condition is not met, I use an empty GUID, '00000000-0000-0000-0000-000000000000', and assign an empty set of permissions, effectively making it a no-op.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",

  "variables": {
    "keyVaultNoPermissions": { },
    "keyVaultAllPermissions": {
      "keys": ["all"],
      "secrets": ["all"],
      "certificates": ["all"],
      "storage": ["all"]
    }
  },

  "resources": [
    // ...
    {
      "type": "Microsoft.KeyVault/vaults/accessPolicies",
      "apiVersion": "2016-10-01",
      "name": "[concat(parameters('keyVaultName'), '/add')]",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[parameters('keyVaultName')]"
      ],
      "properties": {
        "accessPolicies": [
          {
            "tenantId": "[subscription().tenantId]",
            "objectId": "[if(parameters('someCondition'), reference(variables('someAppServiceResourceId'), '2015-08-31-PREVIEW').principalId, '00000000-0000-0000-0000-000000000000')]",
            "permissions": "[if(parameters('someCondition'), variables('keyVaultAllPermissions'), variables('keyVaultNoPermissions'))]"
          },
          {
            "tenantId": "[subscription().tenantId]",
            "objectId": "[if(parameters('otherCondition'), reference(variables('someOTHERAppServiceResourceId'), '2015-08-31-PREVIEW').principalId, '00000000-0000-0000-0000-000000000000')]",
            "permissions": "[if(parameters('otherCondition'), variables('keyVaultAllPermissions'), variables('keyVaultNoPermissions'))]"
          }
        ]
      }
    }
  ]
}
14207973
  • 489
  • 6
  • 19