Search code examples
azureimportterraformiaas

Cannot create network infrastructure


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?


Solution

  • 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:

    • VNet integration using a delegated subnet (subnet_apps)
    • private endpoint in a different subnet

    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.