I currently have an ARM Template that deploys a Virtual Network with a Subnet along with an Azure SQL Database instance.
The core resources related to the Subnet and SQL Firewall Rules are:
{
"name": "MyVirtualNetwork",
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2019-11-01",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups', variables('vmNSG'))]"
],
"properties": {
"addressSpace": {
"addressPrefixes": [
"10.0.0.0/16"
]
},
"subnets": [
{
"name": "Client-Subnet",
"properties": {
"addressPrefix": "10.0.0.0/24",
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('vmNSG'))]"
}
}
}
]
}
},
{
"type": "Microsoft.Network/virtualNetworks/subnets",
"apiVersion": "2019-11-01",
"name": "NDC-VirtualNetwork/Client-Subnet",
"properties": {
"addressPrefix": "10.0.0.0/24"
},
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', 'NDC-VirtualNetwork')]"
]
}
and
{
"type": "firewallRules",
"apiVersion": "2015-05-01-preview",
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', variables('uniqueSQLName'))]"
],
"location": "[resourceGroup().location]",
"name": "AllowAllWindowsAzureIps",
"properties": {
"startIpAddress": "0.0.0.0",
"endIpAddress": "0.0.0.0"
}
},
{
"type": "firewallRules",
"apiVersion": "2015-05-01-preview",
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', variables('uniqueSQLName'))]"
],
"location":"[resourceGroup().location]",
"name": "ClientIP",
"properties": {
"startIpAddress": "[parameters('clientIP')]",
"endIpAddress": "[parameters('clientIP')]"
}
}
I now want to update the Template to permit VNET Service Endpoints from this Subnet to access SQL and to remove the "AllowAllWindowsAzureIPs" and "ClientIP" firewall rules.
To achieve this, I remove both firewallRules resources from the SQL resource and add the following:
{
"name": "[concat(variables('uniqueSQLName'), '-Client-Subnet')]",
"type": "virtualNetworkRules",
"apiVersion": "2015-05-01-preview",
"properties": {
"virtualNetworkSubnetId": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'NDC-VirtualNetwork', 'Client-Subnet')]",
"ignoreMissingVnetServiceEndpoint": true
},
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', variables('uniqueSQLName'))]"
]
}
and then update the Networking resources to :
{
"name": "MyVirtualNetwork",
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2019-11-01",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups', variables('vmNSG'))]"
],
"properties": {
"addressSpace": {
"addressPrefixes": [
"10.0.0.0/16"
]
},
"subnets": [
{
"name": "Client-Subnet",
"properties": {
"addressPrefix": "10.0.0.0/24",
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('vmNSG'))]"
},
"serviceEndpoints": [
{
"service": "Microsoft.Sql",
"locations": [
"australiaeast"
]
}
]
}
}
]
}
},
{
"type": "Microsoft.Network/serviceEndpointPolicies",
"apiVersion": "2019-11-01",
"name": "AllowVNETtoSQL",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', 'MyVirtualNetwork')]",
"[resourceId('Microsoft.Sql/servers', variables('uniqueSQLName'))]"
],
"properties": {
"serviceEndpointPolicyDefinitions": [
{
"name": "AllowVNETtoSQLPolicy",
"properties": {
"service": "Microsoft.Sql",
"serviceResources": [
"[resourceId('Microsoft.Sql/servers', variables('uniqueSQLName'))]"
]
}
}
]
}
},
{
"type": "Microsoft.Network/virtualNetworks/subnets",
"apiVersion": "2019-11-01",
"name": "MyVirtualNetwork/Client-Subnet",
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks','MyVirtualNetwork')]",
"[resourceId('Microsoft.Network/serviceEndpointPolicies','AllowVNETtoSQL')]"
],
"properties": {
"addressPrefix": "10.0.0.0/24",
"serviceEndpointPolicies": [
{
"id": "[resourceId('Microsoft.Network/serviceEndpointPolicies','AllowVNETtoSQL')]"
}
],
"serviceEndpoints": [
{
"service": "Microsoft.Sql",
"locations": [
"australiaeast"
]
}
]
}
}
I get two errors from this change:
My questions are as follows:
"ignoreMissingVnetServiceEndpoint": true
My understanding of this is that the SQL resource would create the Service Endpoint firewall rule OK and skip any checking of the Subnet state and the Subnet would then happily transition into the enabled state and future connections would be allowed.So, I got this to work as follows:
For the virtualNetworkRules I added a dependency to the subnet
{
"type": "Microsoft.Sql/servers/virtualNetworkRules",
"apiVersion": "2015-05-01-preview",
"name": "[concat(variables('uniqueSQLName'), '/ClientSubnet')]",
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', variables('uniqueSQLName'))]",
"[resourceId('Microsoft.Network/virtualNetworks/subnets', 'MyVirtualNetwork', 'Client-Subnet')]"
],
"properties": {
"virtualNetworkSubnetId": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'MyVirtualNetwork', 'Client-Subnet')]",
"ignoreMissingVnetServiceEndpoint": true
}
}
I then updated the virtualNetwork to:
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2020-05-01",
"name": "MyVirtualNetwork",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups', variables('vmNSG'))]"
],
"properties": {
"addressSpace": {
"addressPrefixes": [
"10.0.0.0/16"
]
},
"subnets": [
{
"name": "Client-Subnet",
"properties": {
"addressPrefix": "10.0.0.0/24",
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('vmNSG'))]"
},
"serviceEndpoints": [
{
"service": "Microsoft.Sql",
"locations": [
"[resourceGroup().location]"
]
}
],
"PrivateEndpointNetworkPolicies": "Disabled",
"PrivateLinkServiceNetworkPolicies": "Disabled"
}
}
]
}
}
and included a subnet resource:
{
"type": "Microsoft.Network/virtualNetworks/subnets",
"apiVersion": "2020-05-01",
"name": "[concat('MyVirtualNetwork', '/Client-Subnet')]",
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', 'MyVirtualNetwork')]",
"[resourceId('Microsoft.Network/networkSecurityGroups', variables('vmNSG'))]"
],
"properties": {
"addressPrefix": "10.0.0.0/24",
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('vmNSG'))]"
},
"serviceEndpoints": [
{
"service": "Microsoft.Sql",
"locations": [
"[resourceGroup().location]"
]
}
],
"PrivateEndpointNetworkPolicies": "Disabled",
"PrivateLinkServiceNetworkPolicies": "Disabled"
}
}
Everything seems to be happily working with that config.
NOTE - I also change the API version on some of these resources - not sure if that had an impact as well