0

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"
}
skinex
  • 23
  • 1
  • 4

1 Answers1

0

To clear the confusion here , As per the Microsoft Documentation shared by you it says :

When creating or updating a matched resource in a Resource Manager mode, deny prevents the request before being sent to the Resource Provider. The request is returned as a 403 (Forbidden).

Which means that neither the KeyVault or Private Endpoint can be created in the same template if the effect is set to Deny. The Effect should be Audit only for the policy to be effective properly.

I tested this using portal and its same as the template :

Scenario 1: Effect: Deny

Even if I add a private endpoint while deploying the Keyvault, the validation fails.

enter image description here

Scenario 2: Effect:Audit

I tried creating a keyvault without private endpoint evenif the validation passes , after clicking on create it fails as per policy.

enter image description here

If I create with a private endpoint then it successfully deploys.

enter image description here

Ansuman Bal
  • 9,705
  • 2
  • 10
  • 27
  • Hmm... On my first try I tested audit effect. And I was able to deploy KV without private endpoint. Of course it was marked by policy as "Non-Compliant" but that's not enough in my case. But if I understood correctly in your case deployment (KV without private endpoint) was blocked by policy (although it's set to 'Audit')? – skinex Sep 30 '21 at 07:15
  • Hello @skinex11,yes it was blocked by policy if I tried to create with public endpoint from portal but adding private deployed sucessfully as shown in image , but in deny no new kv was able to deploy (with public/private endpoint) – Ansuman Bal Sep 30 '21 at 07:20
  • I've tested this in my env and result are different from yours. When policy is set to audit the validation and deployment of KV with no private endpoint finishes without any errors nor warnings. I'm really curious what's the difference between our environments. I have clean Visual Studio subscription for testing set up. – skinex Sep 30 '21 at 07:37
  • @skinex, lets move the disscusion to chat you can join this room :https://chat.stackoverflow.com/rooms/237664/chat-for-ansuman-and-skinex – Ansuman Bal Sep 30 '21 at 07:40