Search code examples
azureazure-web-app-serviceazure-virtual-networkazure-sql-server

VNet Integration For Azure Web App and Azure SQL Server


I have an Azure Web App and an Azure SQL Server, both in the same subscription. Both of them are connected to the same VNet Subnet as shown in the below snapshots. The SQL Server is configured not to Allow Azure Resources and Services to access the server, as it should only permit access from either the connected subnet or a set of IP rules.

Unfortunately, the SQL Server is actively refusing any connection from the web app stating that the web app IP is not allowed to access the server.

The interesting thing is that I have the exact same configuration working on another subscription.

What could I be missing?

Snapshots:

1- Here you can see the web application connected to the "webapps" subnet

enter image description here

2- And here you can see the SQL Server connected to the same subnet

enter image description here

3- And that's the error I get

enter image description here


Solution

  • TLDR

    The configuration is correct, but an app service restart may be required.

    VNET Integration

    The configuration of using a virtual network to connect a web app to a SQL database is correct: if the web app is connected to the same subnet/vnet which is allowed in the database's ACLs, and the Microsoft.Sql service endpoint is enabled on the subnet, the web app is able to communicate to the database. This is the whole reason for service endpoints: you do not need to configure with IP allowances on the database.

    As to why the configuration still resulted in an error, it could be the order in which the resources were configured. We were experiencing the exact same setup and issue (which is what let me to this question)!

    We connected our web app to the subnet/vnet but had not enabled the service endpoint on the subnet. We then added/allowed the subnet/vnet as an ACL in the database, during which we were prompted to enable the Microsoft.Sql service endpoint (we did). However, even after waiting ~20 minutes, we were still seeing the same connection issue.

    However, once we restarted the app service, the issue went away and the web app could connect to the SQL database.

    I suspect the issue is due to enabling the subnet's service endpoint after the app service was connected to the subnet. The app service must need a restart to refresh the app service's vnet config/routing.

    Configuration NOT needed

    Contrary to other answers, you do not need to configure firewall IP allowances nor enable access to Azure services and resources. In fact, there are downsides to both approaches:

    • Enabling access to Azure services and resources allows any Azure-based resource to connect to your database, which includes resources not owned by you. From doc:

      This option configures the firewall to allow all connections from Azure, including connections from the subscriptions of other customers.

    • Unless you're using an App Service Environment (which is significantly more expensive than normal App Service plans), your web app's outbound IP addresses are neither static nor specific to your application. From doc:

      Azure App Service is a multi-tenant service, except for App Service Environments. Apps that are not in an App Service environment (not in the Isolated tier) share network infrastructure with other apps. As a result, the inbound and outbound IP addresses of an app can be different, and can even change in certain situations.

    The second point is further elaborated upon in this Github issue:

    IPs are indeed shared with other App Service plans (including other customer's plans) that are deployed into the same shared webspace. The network resources are shared among the plans in a workspace even if the computing instances are dedicated (e.g. in Standard tier). This is inherent to the App Service multi-tenant model. The only way to have a dedicated webspace (i.e. outbound IPs) is to deploy an App Service plan into an App Service Environment (ASE) (i.e. Isolated tier). ASE is the only thing that offers true single-tenency in App Service.

    So neither of the above options will truly harden your SQL database if you want to isolate communication from only your web app. If you have resources in the same subnet, using vnet integration is the correct way to solve the problem.

    If resources cannot be in the same subnet, the solution is to use Private Endpoints.