Azure Functions can be surprisingly leaky, and the default public endpoint is often a much bigger security hole than people realize.

Let’s see what this actually looks like in the wild. Imagine a function app that processes sensitive customer data. By default, it’s accessible from the public internet.

{
  "name": "my-sensitive-data-function-app",
  "location": "eastus",
  "properties": {
    "state": "Running",
    "hostNames": [
      "my-sensitive-data-function-app.azurewebsites.net",
      "my-sensitive-data-function-app.scm.azurewebsites.net"
    ],
    "enabledHostNames": [
      "my-sensitive-data-function-app.azurewebsites.net",
      "my-sensitive-data-function-app.scm.azurewebsites.net"
    ]
  }
}

This hostNames array is the smoking gun: your function is reachable from anywhere. If there’s a vulnerability in your code, or even a misconfigured HTTP trigger, the whole world can potentially hit it.

The solution is Azure Private Endpoints. They allow you to access your Azure services through a private IP address within your virtual network, effectively removing them from the public internet.

Here’s the process:

  1. Create a Virtual Network (VNet) and Subnet: This is where your private endpoint will reside.
    az network vnet create \
      --name MyVNet \
      --resource-group MyResourceGroup \
      --location eastus \
      --address-prefix 10.0.0.0/16
    
    az network vnet subnet create \
      --name MySubnet \
      --resource-group MyResourceGroup \
      --vnet-name MyVNet \
      --address-prefix 10.0.1.0/24
    
  2. Create the Private Endpoint: This links your VNet to the Function App.
    az network private-endpoint create \
      --name MyFunctionAppPrivateEndpoint \
      --resource-group MyResourceGroup \
      --vnet-name MyVNet \
      --subnet MySubnet \
      --private-connection-resource-id "/subscriptions/<YOUR_SUB_ID>/resourceGroups/MyResourceGroup/providers/Microsoft.Web/sites/my-sensitive-data-function-app" \
      --group-ids "sites" \
      --connection-name MyFunctionAppConnection \
      --location eastus
    
    • --private-connection-resource-id: This is the ARM ID of your Function App.
    • --group-ids "sites": This specifies that you’re connecting to the "sites" resource provider of the Function App.
  3. Configure Private DNS: This is crucial. You need to resolve the Function App’s hostname to the private IP address assigned to the private endpoint.
    • First, create a private DNS zone for azurewebsites.net.
      az network private-dns zone create \
        --resource-group MyResourceGroup \
        --name private.azurewebsites.net
      
    • Then, link this zone to your VNet.
      az network private-dns link vnet create \
        --resource-group MyResourceGroup \
        --name MyVNetLink \
        --zone-name private.azurewebsites.net \
        --virtual-network MyVNet \
        --registration-enabled false
      
    • Finally, create an A record in the private DNS zone for your Function App. The private IP will be visible in the output of the az network private-endpoint create command. Let’s assume it’s 10.0.1.4.
      az network private-dns record-set a add-record \
        --resource-group MyResourceGroup \
        --zone-name private.azurewebsites.net \
        --record-set-name my-sensitive-data-function-app \
        --ipv4-address 10.0.1.4
      

After this, my-sensitive-data-function-app.azurewebsites.net will resolve to 10.0.1.4 only from within MyVNet. To ensure the public endpoint is truly inaccessible, you’d then go to your Function App’s "Networking" settings in the Azure portal and enforce access restrictions, effectively disabling public access.

The magic here is that the DNS resolution changes. Instead of pointing to a public IP, it points to a private IP within your VNet. Any traffic destined for your Function App now travels over the Azure backbone network, never hitting the public internet.

This setup requires careful DNS management. If your private DNS zone isn’t correctly configured, or if you’re trying to access the Function App from outside the VNet without proper peering or VPNs, name resolution will fail, and you won’t be able to reach your function.

The next hurdle you’ll likely encounter is managing other Azure services that your Function App needs to communicate with. If those services also require private access, you’ll need to set up private endpoints for them as well, often within the same VNet, to maintain an entirely private data flow.

Want structured learning?

Take the full Azure-functions course →