Kudu and hence storage of function app not accessible after enabling Private endpoint using ARM

Raja Sekhar Narsapuram 0 Reputation points Microsoft Employee
2024-06-21T14:13:40.16+00:00

I have existing function app. We want to move this app into Vnet and isolate storage it connects to stop public access. When I create private endpoints manually everything works as expected. However when I do it using ARM template connection to storage from Function app fails. Has anyone gone into such situations?

Function app is in EP plan

Azure Functions
Azure Functions
An Azure service that provides an event-driven serverless compute platform.
4,646 questions
Azure Blob Storage
Azure Blob Storage
An Azure service that stores unstructured data in the cloud as blobs.
2,625 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Sina Salam 7,206 Reputation points
    2024-06-23T22:22:16.4766667+00:00

    Hello Raja Sekhar Narsapuram,

    Welcome to the Microsoft Q&A and thank you for posting your questions here.

    Problem

    I understand that you have an existing Azure Function App and wants to move it into a Virtual Network (VNet) to isolate the storage it connects to by stopping public access and you have also successfully created private endpoints manually and confirmed that everything works as expected. But you're attempting to automate this process using an ARM (Azure Resource Manager) template, the connection to the storage from the Function App fails.

    Solution

    To solve the problem of integrating your Azure Function App into a Virtual Network (VNet) and isolating its storage account using an ARM template, you will need to follow the below steps:

    NB: There are some of this steps you might have done correctly, try to check out which part is missing.

    First, you need to create a VNet with subnets. One subnet will be for the Function App and the other for the private endpoints.

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "resources": [
        {
          "type": "Microsoft.Network/virtualNetworks",
          "apiVersion": "2020-11-01",
          "name": "myVNet",
          "location": "[resourceGroup().location]",
          "properties": {
            "addressSpace": {
              "addressPrefixes": ["10.0.0.0/16"]
            },
            "subnets": [
              {
                "name": "default",
                "properties": {
                  "addressPrefix": "10.0.1.0/24"
                }
              },
              {
                "name": "privateEndpointSubnet",
                "properties": {
                  "addressPrefix": "10.0.2.0/24",
                  "privateEndpointNetworkPolicies": "Disabled"
                }
              }
            ]
          }
        }
      ]
    }
    

    Secondly, update the Function App to use VNet integration.

    {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2020-12-01",
      "name": "[parameters('functionAppName')]",
      "location": "[resourceGroup().location]",
      "properties": {
        "virtualNetworkSubnetId": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'myVNet', 'default')]"
      }
    }
    

    Thirdly, create private endpoints to connect your storage account securely within the VNet.

    {
      "type": "Microsoft.Network/privateEndpoints",
      "apiVersion": "2020-11-01",
      "name": "[concat(parameters('storageAccountName'), '-pe')]",
      "location": "[resourceGroup().location]",
      "properties": {
        "subnet": {
          "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'myVNet', 'privateEndpointSubnet')]"
        },
        "privateLinkServiceConnections": [
          {
            "name": "[concat(parameters('storageAccountName'), '-connection')]",
            "properties": {
              "privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
              "groupIds": ["blob"]
            }
          }
        ]
      }
    }
    

    Fourthly, set up the storage account to deny public access and allow only access through private endpoints.

    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2021-02-01",
      "name": "[parameters('storageAccountName')]",
      "properties": {
        "networkAcls": {
          "defaultAction": "Deny",
          "bypass": "AzureServices",
          "virtualNetworkRules": [
            {
              "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'myVNet', 'privateEndpointSubnet')]"
            }
          ],
          "ipRules": []
        }
      }
    }
    

    Lastly, ensure that DNS settings allow your Function App to resolve the private endpoint’s DNS name. This involves creating a private DNS zone, linking it to the VNet, and adding the necessary records.

    References

    Kindly use the available additional resources by the right side of this page for more reading and troubleshooting steps.

    Accept Answer

    I hope this is helpful! Do not hesitate to let me know if you have any other questions.

    ** Please don't forget to close up the thread here by upvoting and accept it as an answer if it is helpful ** so that others in the community facing similar issues can easily find the solution.

    Best Regards,

    Sina Salam


  2. Pinaki Ghatak 3,185 Reputation points Microsoft Employee
    2024-07-03T09:39:49.7566667+00:00

    Hello @Raja Sekhar Narsapuram

    Here are some general troubleshooting steps that may help you resolve the issue.

    First, make sure that you have correctly configured your ARM template (preferably Bicep now) to create the necessary resources, including the virtual network, subnet, storage account, and private endpoints. You can refer to the Azure Functions with Virtual Network tutorial for guidance on how to set up these resources.

    Next, check that the private endpoint connection is correctly configured. You can do this by verifying that the private endpoint is in the same subnet as the function app and that the private DNS zone is correctly configured.

    You can also check that the private endpoint is correctly configured to allow traffic to the storage account. If you have verified that the private endpoint connection is correctly configured, you can try troubleshooting the connection between the function app and the storage account.

    One common issue is that the function app may not be able to resolve the DNS name of the storage account. You can try adding the storage account name to the hosts file on the function app to see if this resolves the issue.

    If you are still experiencing issues, you may want to check the logs for your function app and storage account to see if there are any error messages that can help you diagnose the issue.

    That should help.


    I hope that this response has addressed your query and helped you overcome your challenges. If so, please mark this response as Answered. This will not only acknowledge our efforts, but also assist other community members who may be looking for similar solutions.