azure-resource-manager-schemas: KeyVault Schema Requires Access Policy - Docs Say It Is Not Required

In the Microsoft.KeyVault/vaults docs, it says that accessPolicies is not required:

image

When I deploy with this resource, I get no errors

{
    "type": "Microsoft.KeyVault/vaults",
    "name": "[variables('keyVaultName')]",
    "apiVersion": "2018-02-14",
    "location": "[resourceGroup().location]",
    "tags": {},
    "scale": null,
    "properties": {
        "sku": "[parameters('keyVaultSku')]",
        "tenantId": "[parameters('tenantId')]",
        "accessPolicies": [],
        "enabledForDeployment": false,
        "enabledForDiskEncryption": false,
        "enabledForTemplateDeployment": false
    },
    "dependsOn": []
}

When I deploy with this resource (accessPolicies missing)

{
    "type": "Microsoft.KeyVault/vaults",
    "name": "[variables('keyVaultName')]",
    "apiVersion": "2018-02-14",
    "location": "[resourceGroup().location]",
    "tags": {},
    "scale": null,
    "properties": {
        "sku": "[parameters('keyVaultSku')]",
        "tenantId": "[parameters('tenantId')]",
        "enabledForDeployment": false,
        "enabledForDiskEncryption": false,
        "enabledForTemplateDeployment": false
    },
    "dependsOn": []
}

I get this error:

image

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 7
  • Comments: 18 (5 by maintainers)

Most upvoted comments

Very weird behavior, it makes ARM templates for KeyVault almost useless without external scripts…

So on the one side we have the “Use ARM to automatically deploy all things”, and on the other side we have “be secure, use keyvault, no extra code needed”, but we cant use both.

I need to have managed identites added dynamically. I want to be able to redeploy my keyvault and not having access policies wiped.

I am leaving a comment here, so I get updates! Please tell me when this is fixed, or if it will be fixed. I see this as a bug, and not a feature.

Weird that this was just closed without any comment at all…

The template schema and documentation are automatically generated from the REST API spec. In the REST API this property is optional because it can be omitted when recovering a soft-deleted vault (the existing access policy will be restored). The docs have been updated to indicate that this field is only optional when createMode is recover. The access policies are also optional when you use PATCH instead of PUT. We discussed the possibility of adding patch semantics to the PUT API for template deployments, but the proposal was rejected by the Azure Resource Manager team. If you know the vault already exists you can use the reference() function to get the current access policies and append an entry. The ARM team had a proposed feature that would let you handle the case where the vault didn’t exist, but I don’t think it’s possible with the current template language.

Simply including “accessPolicies”: [] is a perfect workaround for me. It seems like a documentation issue, maybe update the documentation accessPolicies as required but nullable.

No, setting that empty array would wipe any access policies already there until applied again, that’s the whole issue basicly, we are required to input the accessPolicies and therefor wiping anything there. That in combination with no real support for checking if resources are already existent within ARM/bicep makes this a huge issue.

ANY UPDATES SOON?

@mslot Agreed, it’s unacceptable that such a seemingly common use-case can’t be achieved using ARM. For anyone having the same issue, the closest I came to an acceptable solution is making the value of both the accessPolicies and create mode conditional based on a parameter that specifies if the key vault already exists withing the target resource group (see below). This allows you to either set this value manually before deploying the template for the first time to a given resource group or determine if the resource already exists using some external script. When the parameter is set to true', the template will use the recovermode which makes theaccessPoliciesparameter optional, allowing you to passnull` which will not remove any existing access policies when deploying the template.

"accessPolicies": "[if(parameters('My.KeyVault.existsWithinTargetResourceGroup'), json('null'), json('[]'))]",
"createMode": "[if(parameters('My.KeyVault.existsWithinTargetResourceGroup'), 'recover', 'create')]",

My team moved to RBAC keyvaults specifically to avoid this problem while building out our new services. Doing so completely mitigated the problem I described\encountered earlier in the thread.

@wouterroos That’s something of an abuse of the createMode parameter. It happens to work because we return a 200 if you attempt to recover a vault that hasn’t been deleted yet and we aren’t enforcing the absence of other properties during recovery. But if you are going to have a parameter that indicates whether the vault exists or not, you could simply make the entire vault conditional on that parameter without relying on this behavior.

In general, the direction ARM is going in is to support DataActions in ARM RBAC policies rather than have each service provide its own access control mechanism. If Key Vault were to support data actions the same way Storage does, it would remove the need to update the vault to grant access to its contents.