Azure PostgreSQL Flexible Server meet with Azure Landing Zone
Azure PostgreSQL Flexible Server is a fully managed database service that allows you to run, manage, and scale PostgreSQL databases in the cloud. It provides built-in high availability, automated backups, and scaling capabilities. Azure PostgreSQL Flexible Server is an excellent choice for developers who want to focus on building applications rather than managing infrastructure.
In Azure, if you want to use PostgreSQL, you will use this service and must integrate it with your Azure Landing Zone. Unlike the previous Azure PostgreSQL service, this one is VNet-integrated and requires a dedicated Private DNS Zone for the service.
This presents a challenge because, in the Azure Landing Zone, you do not have permission to create a new Private DNS Zone and attach it to the central VNet where your DNS resolvers are working. So how can you solve this problem? With Azure Policy, of course!
Here is the policy definition you can use to create a VNet link between the Private DNS Zone (which you created alongside the PostgreSQL Flexible Server) and the VNet used by everyone else in the Azure Landing Zone.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
{
"mode": "All",
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Network/privateDnsZones"
},
{
"field": "name",
"like": "[concat('*',parameters('pDnsZones'))]"
}
]
},
"then": {
"effect": "deployIfNotExists",
"details": {
"evaluationDelay": "AfterProvisioningSuccess",
"type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks",
"name": "[parameters('virtualNetworkLinkName')]",
"roleDefinitionIds": [
"/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7"
],
"existenceCondition": {
"field": "Microsoft.Network/privateDnsZones/virtualNetworkLinks/virtualNetwork.id",
"equals": "[parameters('targetVnet')]"
},
"deployment": {
"properties": {
"mode": "incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"privateDNSZoneName": {
"type": "string"
},
"virtualNetworkLinkName": {
"type": "string"
},
"targetVnetId": {
"type": "string"
}
},
"resources": [
{
"name": "[concat(parameters('privateDNSZoneName'), '/', parameters('virtualNetworkLinkName'))]",
"type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks",
"apiVersion": "2024-06-01",
"tags": {},
"location": "global",
"properties": {
"virtualNetwork": {
"id": "[parameters('targetVnetId')]"
},
"registrationEnabled": false
}
}
]
},
"parameters": {
"privateDNSZoneName": {
"value": "[field('name')]"
},
"virtualNetworkLinkName": {
"value": "[parameters('virtualNetworkLinkName')]"
},
"targetVnetId": {
"value": "[parameters('targetVnet')]"
}
}
}
}
}
}
},
"parameters": {
"virtualNetworkLinkName": {
"type": "String",
"metadata": {
"displayName": "Virtual Network Link Name",
"description": "The name of the virtual network link to create"
}
},
"targetVnet": {
"type": "String",
"metadata": {
"displayName": "Target virtual network",
"description": "The target virtual network for Private DNS zone connections"
}
},
"pDnsZones": {
"type": "String",
"metadata": {
"displayName": "Private DNS zones",
"description": "Name of the private dns zones what effected, like .postgres.database.azure.com"
},
"defaultValue": ".postgres.database.azure.com"
}
}
}
I recommend to create User Defined Managed Identity what will be used by the policy to create the Vnet link because you can reuse this policy for AKS as well and every future service what will need a Private DNS Zone dedicated for them.