Serverless VNet Integration in Azure

Serverless functions and App Service apps are easy to deploy, but they run outside your VNet by default. When they need to call your internal database, hit a private API, or access storage through a private endpoint, they cannot — they are on Azure’s public infrastructure, not inside your network. VNet integration changes that.

What VNet integration does

VNet integration connects an App Service or Azure Functions app to a subnet in your VNet. This gives the app outbound access to resources inside the VNet — private databases, storage accounts with private endpoints, internal APIs, and on-premises resources via VPN or ExpressRoute.

Important: VNet integration is one-directional for outbound traffic. It lets the app call resources inside the VNet. It does not prevent the app from being reached via its public URL, and it does not give the app a private IP. For inbound private access to the app, you need a separate Private Endpoint on the app itself.

Regional VNet integration

Regional VNet integration is the modern, recommended approach. It works by delegating a subnet to the App Service or Functions plan. Azure injects virtual network interfaces into that subnet on behalf of the app when it makes outbound calls.

Requirements for regional VNet integration:

- The VNet must be in the same region as the App Service plan.

- A dedicated subnet for the integration. The subnet cannot be shared with VMs or other resources.

- Minimum subnet size: /28 (11 usable IPs). Recommended: /26 or larger for scale sets and multiple apps.

- The subnet must be delegated to Microsoft.Web/serverFarms.

Setting up VNet integration with the CLI

Create a dedicated subnet for VNet integration and delegate it to App Service:

# Create the integration subnet
az network vnet subnet create \
  --name snet-appservice-integration \
  --resource-group rg-prod-networking \
  --vnet-name vnet-prod-eastus-001 \
  --address-prefixes 10.0.10.0/26 \
  --delegations Microsoft.Web/serverFarms

Create an App Service plan (Premium P1v3 for VNet integration support):

az appservice plan create \
  --name asp-prod-premium \
  --resource-group rg-prod-apps \
  --location eastus \
  --sku P1v3 \
  --is-linux

Create a function app on the premium plan:

az functionapp create \
  --name func-backend-prod \
  --resource-group rg-prod-apps \
  --plan asp-prod-premium \
  --storage-account mystorageaccountprod \
  --runtime python \
  --runtime-version 3.11 \
  --os-type Linux

Enable VNet integration for the function app:

az functionapp vnet-integration add \
  --name func-backend-prod \
  --resource-group rg-prod-apps \
  --vnet vnet-prod-eastus-001 \
  --subnet snet-appservice-integration

Verify the integration is active:

az functionapp vnet-integration list \
  --name func-backend-prod \
  --resource-group rg-prod-apps

Routing all outbound traffic through the VNet

By default, VNet integration only routes traffic destined for private IP ranges through the VNet. Public internet traffic from the app still goes out directly. To force all outbound traffic (including internet traffic) through the VNet — for example, to route it through Azure Firewall — enable the WEBSITE_VNET_ROUTE_ALL setting:

az functionapp config appsettings set \
  --name func-backend-prod \
  --resource-group rg-prod-apps \
  --settings WEBSITE_VNET_ROUTE_ALL=1

With this setting enabled, all outbound traffic from the function app routes through the integration subnet. If you have a route table on that subnet pointing to Azure Firewall, the firewall can inspect and control the function app’s internet traffic.

Note

When WEBSITE_VNET_ROUTE_ALL=1 is enabled, the app needs a way to reach the internet through the VNet — either a NAT Gateway on the integration subnet or Azure Firewall in the hub. Without an outbound internet path, the app will lose internet connectivity entirely.

Private DNS resolution for serverless apps

When a function app calls a storage account with a private endpoint, DNS must resolve the storage hostname to the private IP. By default, VNet-integrated apps use Azure’s public DNS, which returns the public IP. Configure the app to use Azure Private DNS by setting the DNS server:

# Point the app to Azure's private DNS resolver (168.63.129.16 via VNet)
az functionapp config appsettings set \
  --name func-backend-prod \
  --resource-group rg-prod-apps \
  --settings WEBSITE_DNS_SERVER=168.63.129.16

168.63.129.16 is Azure’s internal DNS resolver. When the app queries it through the VNet integration, it uses the VNet’s DNS configuration, which includes Private DNS zone resolution.

Private inbound access to the app

VNet integration handles outbound access. For private inbound access (preventing the app from being reached via its public URL), create a Private Endpoint on the app:

# Get the app's resource ID
APP_ID=$(az functionapp show \
  --name func-backend-prod \
  --resource-group rg-prod-apps \
  --query id \
  --output tsv)

# Create a private endpoint for the function app
az network private-endpoint create \
  --name pe-func-backend \
  --resource-group rg-prod-networking \
  --vnet-name vnet-prod-eastus-001 \
  --subnet snet-privateendpoints \
  --private-connection-resource-id $APP_ID \
  --group-id sites \
  --connection-name conn-func-backend

After adding a private endpoint, disable public access on the app:

az functionapp update \
  --name func-backend-prod \
  --resource-group rg-prod-apps \
  --set publicNetworkAccess=Disabled

Common mistakes

  1. Sharing the integration subnet with other resources. The integration subnet must be delegated to App Service and cannot contain VMs, private endpoints, or other resources. Attempting to place a VM in the integration subnet will fail. Create a dedicated subnet sized appropriately for the number of app instances.
  2. Not configuring DNS when calling private endpoints. The most common symptom is a connection timeout when calling a storage account or database via its private endpoint. The function app has network connectivity through VNet integration, but DNS returns the public IP. Set WEBSITE_DNS_SERVER=168.63.129.16 to enable private DNS resolution through the VNet.
  3. Using Consumption plan and expecting VNet integration. Consumption plan Azure Functions scale to zero on shared infrastructure and do not support VNet integration. If you need VNet integration with scale-to-zero, use Premium Elastic plan or Azure Container Apps with serverless scaling enabled.

Frequently asked questions

Does VNet integration give the function app a private IP inside the VNet?

Not exactly. VNet integration allows the function app to make outbound calls to resources in the VNet, but the function app itself does not get a private IP in the VNet. Inbound traffic to the function app still uses its public URL. For private inbound access, use Private Endpoints on the function app itself.

What is the difference between regional VNet integration and gateway-required VNet integration?

Regional VNet integration uses a dedicated subnet in the same region and does not require a VPN gateway. It is faster, lower latency, and the recommended approach for new deployments. Gateway-required integration is an older method for connecting to VNets in other regions.

Does VNet integration work with consumption plan Azure Functions?

Regional VNet integration requires at minimum a Premium plan for Azure Functions or a Basic plan for App Service. Consumption plan functions do not support VNet integration. Consider upgrading to Premium plan or using Azure Container Apps if you need VNet integration with serverless scale-to-zero.

Last verified: 19 March 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.