I have an existing infrastructure (Two App services, one Azure SQL Db, one Blob storage, one CosmosDB). We want to create it behind a virtual network and private endpoints. Our code looks like this:
resource "azurerm_windows_web_app" "spa" {
name = "${var.app_service_name}Spa${title(var.environment)}"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
service_plan_id = azurerm_service_plan.app_plan.id
app_settings = {
APPLICATIONINSIGHTS_CONNECTION_STRING = azurerm_application_insights.spaai.connection_string
WEBSITE_RUN_FROM_PACKAGE = 0
}
site_config { }
lifecycle {
ignore_changes = [
site_config["scm_type"]
]
}
tags = {
environment = var.environment
}
https_only = true
}
// More infra here
resource "azurerm_virtual_network" "vnet" {
name = "vnet-${var.environment}"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
address_space = ["10.0.0.0/16"]
}
resource "azurerm_subnet" "subnet_gateway" {
name = "default"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.0.0.0/24"]
}
resource "azurerm_subnet" "subnet_apps" {
name = "apps"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.0.1.0/24"]
delegation {
name = "apps-subnet-delegation"
service_delegation {
name = "Microsoft.Web/serverFarms"
actions = [ "Microsoft.Network/virtualNetworks/subnets/action" ]
}
}
enforce_private_link_endpoint_network_policies = false
enforce_private_link_service_network_policies = false
}
resource "azurerm_private_endpoint" "spa_endpoint" { <- Here we get an error !
name = "${azurerm_windows_web_app.spa.name}-endpoint"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
subnet_id = azurerm_subnet.subnet_apps.id
private_service_connection {
name = "${azurerm_windows_web_app.spa.name}-privateconnection"
private_connection_resource_id = azurerm_windows_web_app.spa.id
subresource_names = ["sites"]
is_manual_connection = false
}
}
When I run this, I get:
Error: creating Private Endpoint (Subscription: "code"
│ Resource Group Name: "tms-staging-rg"
│ Private Endpoint Name: "Tms2WebSpaStaging-endpoint"): performing CreateOrUpdate: unexpected status 400 with error: PrivateEndpointCreationNotAllowedAsSubnetIsDelegated: Private endpoint /subscriptions/code/resourceGroups/tms-staging-rg/providers/Microsoft.Network/privateEndpoints/Tms2WebSpaStaging-endpoint cannot be created as subnet /subscriptions/code/resourceGroups/tms-staging-rg/providers/Microsoft.Network/virtualNetworks/vnet-staging/subnets/apps is delegated.
│
│ with azurerm_private_endpoint.spa_endpoint,
│ on main.tf line 1688, in resource "azurerm_private_endpoint" "spa_endpoint":
│ 1688: resource "azurerm_private_endpoint" "spa_endpoint" {
If I remove delegation
block from the subnet_apps
, then we get another error:
Error: updating Subnet (Subscription: "code"
│ Resource Group Name: "tms-staging-rg"
│ Virtual Network Name: "vnet-staging"
│ Subnet Name: "apps"): network.SubnetsClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="SubnetMissingRequiredDelegation" Message="Subnet /subscriptions/code/resourceGroups/tms-staging-rg/providers/Microsoft.Network/virtualNetworks/vnet-staging/subnets/apps requires any of the following delegation(s) [Microsoft.Web/serverFarms] to reference service association link /subscriptions/code/resourceGroups/tms-staging-rg/providers/Microsoft.Network/virtualNetworks/vnet-staging/subnets/apps/serviceAssociationLinks/AppServiceLink." Details=[]
│
│ with azurerm_subnet.subnet_apps,
│ on main.tf line 1618, in resource "azurerm_subnet" "subnet_apps":
│ 1618: resource "azurerm_subnet" "subnet_apps" {
We use Terraform 1.5, Azure RM 3.65.
What is the issue here?
As per Microsoft's docs, a subnet
Can't be used with a private endpoint if the subnet is delegated
Thus, you need to use another subnet for your private endpoint(s), and the app service will have to be configured as follows:
subnet_apps
)As a side note, my advice is to first create a replica of your infrastructure through Azure's portal to understand how to configure the services and their limitations (in this case, the portal would have blocked you if tried to add a private endpoint to a delegated subnet and viceversa). When you are satisfied with the result, you can write and test a terraform script to automate all the processes.