I need to create policy assignment which will block keyVault deployments without privateEndpoint configured. I tested built-in policy "[Preview]: Azure Key Vaults should use private link" with "Audit" effect and it works fine.
But when I change effect to "Deny" then my deployment is blocked as I'm deploying two resources (keyVault and privateEndpoint) separately. From what I understood from docs (https://learn.microsoft.com/en-us/azure/governance/policy/concepts/effects#deny) the resource is evaluated before sending to Resource provided. Which implicates the policy is not aware of private endpoint (as it's separate resource).
Have anyone faced similar problem and managed to handle it?
I'm pasting my template below:
resource keyVaultPrivateLink 'Microsoft.KeyVault/vaults@2019-09-01' = {
name: kvName
location: location
properties: {
enabledForTemplateDeployment: true
tenantId: tenant
enableRbacAuthorization: true
enablePurgeProtection: true
enableSoftDelete: true
networkAcls: {
bypass: 'AzureServices'
defaultAction: 'Deny'
virtualNetworkRules: [
{
id: subnetId
}
]
}
sku: {
name: 'standard'
family: 'A'
}
}
}
resource keyVaultPrivateEndpoint 'Microsoft.Network/privateEndpoints@2020-03-01' = {
name: 'pewetkvwetprivatelink'
location: location
properties: {
subnet: {
id: subnetId
}
privateLinkServiceConnections: [
{
name: 'kvwetprivatelink'
properties: {
privateLinkServiceId: keyVaultPrivateLink.id
groupIds: [
'vault'
]
}
}
]
}
}
The error code received:
{
"error": {
"code": "InvalidTemplateDeployment",
"message": "The template deployment failed because of policy violation. Please see details for more information.",
"details": [
{
"code": "RequestDisallowedByPolicy",
"target": "keyVault-name",
"message": "Resource 'kvwetprivatelink' was disallowed by policy. Policy identifiers: '[{\"policyAssignment\":{\"name\":\"Audit KeyVault Initiative\",\"id\":\"/subscriptions/***/providers/Microsoft.Authorization/policyAssignments/Audit KeyVault Initiative\"},\"policyDefinition\":{\"name\":\"[Preview]: Azure Key Vaults should use private link\",\"id\":\"/providers/Microsoft.Authorization/policyDefinitions/a6abeaec-4d90-4a02-805f-6b26c4d3fbe9\"},\"policySetDefinition\":{\"name\":\"Audit KeyVault Initiative\",\"id\":\"/subscriptions/***/providers/Microsoft.Authorization/policySetDefinitions/Audit KeyVault Initiative\"}}]'.",
"additionalInfo": [
{
"type": "PolicyViolation",
"info": {
"policyDefinitionDisplayName": "[Preview]: Azure Key Vaults should use private link",
"policySetDefinitionDisplayName": "Audit KeyVault Initiative",
"evaluationDetails": {
"evaluatedExpressions": [
{
"result": "True",
"expressionKind": "Field",
"expression": "type",
"path": "type",
"expressionValue": "Microsoft.KeyVault/vaults",
"targetValue": "Microsoft.KeyVault/vaults",
"operator": "Equals"
},
{
"result": "True",
"expressionKind": "Count",
"expression": "Microsoft.KeyVault/vaults/privateEndpointConnections[*]",
"path": "properties.privateEndpointConnections[*]",
"expressionValue": 0,
"targetValue": 1,
"operator": "Less"
}
]
},
"policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/a6abeaec-4d90-4a02-805f-6b26c4d3fbe9",
"policySetDefinitionId": "/subscriptions/***/providers/Microsoft.Authorization/policySetDefinitions/Audit KeyVault Initiative",
"policyDefinitionReferenceId": "[[Preview]: Azure Key Vaults should use private link",
"policySetDefinitionName": "Audit KeyVault Initiative",
"policyDefinitionName": "a6abeaec-4d90-4a02-805f-6b26c4d3fbe9",
"policyDefinitionEffect": "Deny",
"policyAssignmentId": "/subscriptions/***/providers/Microsoft.Authorization/policyAssignments/Audit KeyVault Initiative",
"policyAssignmentName": "Audit KeyVault Initiative",
"policyAssignmentDisplayName": "Audit KeyVault Initiative",
"policyAssignmentScope": "/subscriptions/***"
}
}
]
}
]
}
}
And policy definition:
{
"properties": {
"displayName": "[Preview]: Azure Key Vaults should use private link",
"policyType": "BuiltIn",
"mode": "Indexed",
"description": "Azure Private Link lets you connect your virtual networks to Azure services without a public IP address at the source or destination. The Private Link platform handles the connectivity between the consumer and services over the Azure backbone network. By mapping private endpoints to key vault, you can reduce data leakage risks. Learn more about private links at: https://aka.ms/akvprivatelink.",
"metadata": {
"version": "1.0.0-preview",
"category": "Key Vault",
"preview": true
},
"parameters": {
"effect": {
"type": "String",
"metadata": {
"displayName": "Effect",
"description": "Enable or disable the execution of the policy"
},
"allowedValues": [
"Audit",
"Deny",
"Disabled"
],
"defaultValue": "Audit"
}
},
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.KeyVault/vaults"
},
{
"count": {
"field": "Microsoft.KeyVault/vaults/privateEndpointConnections[*]",
"where": {
"field": "Microsoft.KeyVault/vaults/privateEndpointConnections[*].privateLinkServiceConnectionState.status",
"equals": "Approved"
}
},
"less": 1
}
]
},
"then": {
"effect": "[parameters('effect')]"
}
}
},
"id": "/providers/Microsoft.Authorization/policyDefinitions/a6abeaec-4d90-4a02-805f-6b26c4d3fbe9",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "a6abeaec-4d90-4a02-805f-6b26c4d3fbe9"
}