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