Showing posts with label Policy. Show all posts
Showing posts with label Policy. Show all posts

Monday, June 10, 2024

Azure policy: Deny VNet peering to non-approved VNets

 As part of the Azure Landing Zone architecture, there is a policy that denies the creation of VNet peerings to non-allowed VNets, see policy here.

This policy is relevant to a apply in a hub-spoke setup where you want to avoid that spoke VNets, or spoke landing zones, can create VNet peerings to anything other than the defined Hub VNets.

At current client we've been running this policy since December, 2023 and it's been working fine.

However, about a month ago some policy evaluation behavior changed (the policy itself or the templates have not changed) and now for certain bicep files, the policy blocks deployments even when using approved VNets for the peering. It wasn't for all bicep files and ARM templates still worked.

Microsoft Support came up with a minor update to the policy definition to effectively have the same rule but the syntax is slightly different. This works.

We haven't found an explanation yet as to why there was a change in policy evaluation behavior.

But the updated policy can be found here on Github.

Tuesday, June 4, 2024

Azure policy: Auto create DNS records in private DNS zones using multiple zones

 There are certain Azure PaaS services that when used together with private endpoints, require not just one A record in one DNS (as is the case for most PaaS services) but multiple A records in multiple private DNS zones (PDNS).

Examples of PaaS services that require this are (see here for full list): 

  • Azure Monitor
  • Power BI
  • Azure Data Explorer
  • Azure Arc
  • Azure Health Data Services

When using private endpoints at scale, MSFT recommends using Azure Policy for the A record creation. I've described this in a previous article, see here.

But the MSFT policy to create DNS records can only handle a single PDNS zone, not multiple PDNS zones.

I found a fix to this on the 'Blog Cloud63' in this post (and here's a direct link to his policy definition), so thanks goes to Vincent Misson for that.

He basically expands on the MSFT policy for the resource 'privateDnsZoneGroups' by adding a copy loop to the properties of the resource. The copy loop then goes through an array of PDNS zone resource IDs and adds multiple items under properties. The privateDnsZoneGroups resource is what actually creates the A record in the PDNS zones.

Below you can see snippet of the code with the copy loop (modified policy):


And without the copy loop (default MSFT policy)


I have uploaded my slightly modified version of the policy to Github.

It has been tested with Azure Monitor, specifically with private endpoints for Azure Monitor Private Link Scope (AMPLS) and it works as expected (11 records are created in 5 separate PDNS zones).



Friday, December 22, 2023

Azure policy: Reducing the default evaluation time for auto A record creation for private endpoints

 I have previously written about the use of Azure policy to automatically create A records for private endpoints in centrally managed private DNS zones. You can see more here and here. And the general recommended setup from MSFT is available here.

One of the slightly annoying things about the standard Azure policies is that they use the default evaluation delay time (10 minutes) for when a DeployIfNotExist policy runs. This means that when you create a private endpoint, it takes around 10 minutes before the A record is created in the private DNS zone. This creates, in addition to the added wait time, some confusion from users as they don't know whether their deployments work or not.

This evaluation delay time can be minimized by using the optional property for DeployIfNotExist type policies called EvaluationDelay. This is described in more detail here.

There are different values that can be set for this property, but to get the best effect, I'd recommend using AfterProvisioningSuccess. This will run the policy as soon as the private endpoint has been successfully deployed.

You can see an example of a policy using this property here on Github. And below is an example as well.

Note that this property does not only apply to DNS record creation. It can be used for other DeployIfNotExist policies as well where you want the resources deployed right away.



Monday, December 11, 2023

Azure policy: Auto create DNS records using both subResource and private link resource type

 When using private endpoints at scale, the recommended setup from Microsoft is to use Azure Policy to automatically create the DNS records in the central private DNS zones when the private endpoints are created. The reason for this is that users or owners of the spokes or landing zones do not have permissions to create A records in the central private DNS zones in the Hub.

For most private DNS zones, the regular Azure policy can be used which checks for private DNS zone name and subResource id, see list here. However, there are scenarios where this is not sufficient. For example, if a region has to be specified using Recovery Services Vault, see more on that here.

Another example, and the scope of this post, is when there are overlapping subResource values such as for Synapse Analytics and Cosmos DB (which both use 'sql') or Synapse Studio and Storage accounts Web (which both use 'web'). If multiple policies are created using the same subResource, you don't know in which private DNS zone that the A record will be created and you can experience records being created first in one zone and then the other whichever policy is evaluated first.

To address this, Microsoft has created a policy that, in addition to the subResource, adds a parameter that matches on the private link resource type (also referred to as privateLinkServiceId). The policy can be found here.

The private link resource type is found in the first column in the table of private DNS zones, here. Examples of values are:

  • Microsoft.Synapse/privateLinkHubs
  • Microsoft.Synapse/workspaces
  • Microsoft.DocumentDB/databaseAccounts

For some odd reason, MSFT hardcodes the value of the private link reosurce type in the policy. I've updated the policy slightly to parameterize that value. The updated policy can be found on here on Github.

Below you can see an example of what it looks like when the policy is assigned in the portal:



Tuesday, October 10, 2023

Add custom rule to new NSGs via Azure Policy

 For governance, or operational, reasons there may be a need to ensure that certain rules are applied to all NSGs that are created within a certain scope.

This can be achieved using Azure Policy with a deployIfNotExist function.

Such a policy has already been created and is ready to use from AzAdvertizer.net, see link here:

I ran a quick test to verify the functionality and it works as expected. At the time of creation of the NSG, the policy kicks in an applies the rule right away.

The policy will let you specify one rule. So for multiple rules additional assignments can be created.

The policy looks for a suffix (the last part of the name) in the NSG name and only applies the rule if there's a match. You can re-arrange the check and have it look for a prefix instead, I have uploaded an example here on Github (can be copied in as a new definition via Azure Portal -> Policy -> Definitions).

If you want to apply the rule to all NSGs, then simply remove this check, see marked part below:


The policy is parameterized, so when you create an assignment it will request you to add all relevant parameters. See example below:

Note that some of the parameters such as destinationPortRange are arrays. They should be added in the format ["3389"] (for port 3389..).


Below is a screenshot of the inbound rule added post NSG deployment:


Since this is a deployIfNotExist policy, this means the Assignment requires a system assigned managed identity (or a user assigned managed identity) with Network Contributor permissions which will be automatically created when you create the assignment if you have enough permissions.




Wednesday, June 7, 2023

Azure Policy - Allow only specified IP ranges and regions for VNets

 At current client we had a request to apply a policy to enforce that only VNets using specified IP address ranges and regions will be allowed. So for example, if you create a VNet in West Europe, then it must be within the 10.100.0.0/16 IP address space and if in North Europe it must be within 10.200.0.0/16 and 10.201.0.0/16. And anything outside that must be denied.

There is no built-in policy for this. It was possible to find simpler versions online of the above but we couldn't find anything that fit all the requirements.

The closest we got was a slimmed down version of this policy from AzPolicyAdvertizer named "Address space must be pre-allocated for region".

However, it didn't take into account extended VNets. So if you have a VNet consisting of two or more IP address ranges, it will show as non-compliant.

We raised a ticket with Microsoft support and after a few days they came back with an updated policy that works.

The functioning policy can be found here on Github. The only thing that needs to be updated is the content of the "spokeAllocations" array.

Monday, March 20, 2023

Auto create DNS records for RSV with policy including region code

 When using private endpoints at scale, the recommended setup from Microsoft is to use Azure Policy to automatically create the DNS records in the central private DNS zones when the private endpoints are created. The reason for this is that users or owners of the spokes or landing zones do not have permissions to create A records in the central private DNS zones in the Hub.

The policies specified by Microsoft work as long as a region code does not have to be specified in the private DNS zone name (which is the case for most of them, see full list here). However, for e.g. Recovery Services Vault for Azure Backup (and for AKS/Kubernetes), this is the case.

The zones are region specific, for West Europe it's: privatelink.we.backup.windowsazure.com and for Sweden Central it's privatelink.sdc.backup.windowsazure.com.

The default policy only does a check on the subResource (or groupId) value which in this case is: AzureBackup. The result of having two policies (e.g. one for West Europe and one for Sweden Central) running with the same subResource value is that DNS records for the private endpoints are randomly generated in the two private DNS zones.

A fix for this is to add a conditional check in the policy on the location of the private endpoint (PE). This way it is ensured that the DNS records are created in the correct zone that matches the location of the PE.

The full policy is available on Github, see link here.

The main change can be seen below: