Home » Connect Azure App Service to virtual network

Connect Azure App Service to virtual network

Let’s assume you have to read data from your on-premise network e.g. from a SAP, ERP or other system. It could also be that you want to have access to your virtual machines in your virtual network.
How to connect to your on-premise environment? Simple answer is: via VPN or ExpressRoute! But that’s just a part of the job, you also have to connect the App service to your virtual network at first. If the web app is in the virtual network, you have access to all resources in the network – virtual machines for example. If the virtual network is connected to your on-premise network, you can also access those resources. This blog post is about how to connect the app service to your virtual network and how to design the network. The VPN connection is not part of this blog post.

Overview

The connection between App Service, virtual network and on-premise network needs the following resources:

  • App Service + Web App/API App/Logic App/Function/…
  • Virtual network
  • Virtual network gateway
  • Point-to-Site VPN from Web App etc. to the virtual network gateway
  • Local network gateway
  • Site-to-Site VPN from Azure virtual network gateway to the local network gateway (VPN device)

Network design

The first thing to do is to define the Azure network address space. You could use each address space and configure routing and other stuff. But the easiest way is to define a unique address space in Azure which is not already in use in your on premise network. Let’s assume you have the following address space reserved for the Azure network:

  • Azure address space: 10.10.0.0/24 (10.10.0.0 – 10.10.0.255)

If you are not familiar with the CIDR notation or you don’t know all the spaces – MX toolbox is a good resource to calculate them: http://mxtoolbox.com/subnetcalculator.aspx

It has a size of 255 addresses which seems to be a lot, but we have to consider that we need address spaces for:

  • Gateway Subnet: The minimal size for the gateway subnet is /29 (8 addresses), but I strongly recommend you to use at least /28 (16 addresses) or even better /27 (32 addresses). The reason for this is, that you probably want to connect additional networks to your virtual network. If you have configured the gateway subnet and you have added the virtual network gateway – there is no way to change the address space. It means: if you need more space, you have to delete the virtual network gateway, change the address space and recreate it. The creation takes about 45 minutes and the recreation will result in a new public IP for your virtual network gateway. As a result, you also have to reconfigure your local VPN device (if you have a vpn connection to your on-premise resources). The gateway subnet is a subnet only for the virtual network gateway, so don’t deploy e.g. virtual machines to it.
  • Default Subnet: The subnet for virtual machines and others. You can e.g. use a virtual machine to test your network related settings.
  • Point-to-site space: The app service will be connected via point-to-site VPN to the virtual network gateway. Therefore, you have to specify an address space for these point-to-site VPN devices. I also tend to use at least /28 for it, because you need to connect every single web app. That means, if you have 5 web apps in one app service, you connect 5 web apps and each gets its own IP address. You can also connect your local client via VPN to test if everything works. It’s important to know that this reserved client address space is not part of the virtual network!

Okay, so we need a few subnets and some space for Point-to-Site VPN. I configured it as follows:

  • Azure address space: 10.10.0.0/24 (10.10.0.0 – 10.10.0.255)
  • Virtual network: 10.10.0.0/25 (10.10.0.0 – 10.10.0.127)
    • Default subnet: 10.10.0.0/26 (10.10.0.0 – 10.10.0.63)
    • Free space: 10.10.0.64/27 (10.10.0.64 – 10.10.0.95) – for future use like backend subnet or any others
    • Gateway subnet: 10.10.0.96/27 (10.10.0.96 – 10.10.0.127)
  • Point-to-site space: 10.10.0.128/26 (10.10.0.128 – 10.10.0.191)
  • Free space: 10.10.0.192/26 (10.10.0.192 – 10.10.0.255) – fur future use – can be added to virtual network or for additional virtual network gateways.

Create the virtual network

First step is to create the virtual network with the parameters defined above – a virtual network with 2 subnets:

Create the virtual network gateway

The app service will be connected via point-to-site VPN to the virtual network. For a point-to-site VPN we have to create a virtual network gateway. The creation takes about 45 minutes (it takes that long because Azure creates an invisible virtual machine running Windows in the background and configures remote access, routing etc.). The gateway type is VPN, the VPN type can be route based and also policy based. If you only want to connect the app service to the virtual network and you have no connection to your on-premise VPN device, then you can simply use route based. If you want a VPN to your local network, the VPN type depends on your security requirements and your on-premise VPN device. Please check the documentation and check what is supported or recommended for your VPN device: https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-about-vpn-devices.

When the virtual network gateway is deployed, we can continue to set the point-to-site configuration. If you immediately try to put the app service to your virtual network, you will see the message “Gateway does not have any point-to-site addresses”.

Configure the point-to-site addresses

Go to your virtual network gateway and to the point-to-site configuration. Add the address space, in our case 10.10.0.128/26 and press save. The message “Add at least one root certificate in order to be able to download the VPN client.” can be ignored as long as we don’t want to connect our client to the virtual network. The certificate for the app service is created and configured automatically.

Connect the app service

The virtual network and the virtual network gateway are created. The point-to-site configuration is done and I assume that the app service already exists. The app service must be standard or premium, basic and free do not support vnet integration.

The next step is the easiest one. Just navigate to the web app, select networking and click on setup:

Select the virtual network and the connection will be established.

Issues and Troubleshooting

Use a virtual machine

One way to troubleshoot the network is to create a virtual machine and try to connect from or to the web app. I currently use a Windows Server 2016 Datacenter image, but an Ubuntu, Windows 10 or anything else will also do the job.

Kudu console

You can use the kudu console and try to ping your client or virtual machine. You can find the kudu console in the web app under development tools. The ping command is tcpping. I created a virtual machine in the virtual network and it got the ip 10.10.0.4 – so the command is:

tcpping 10.10.0.4

I executed it and I got the error:
Connection attempt failed: Connection timed out.

I am pinging a virtual machine and there is a good chance that the vm does not allow incoming pings or that the network security group for the virtual machine blocks them. The good thing is, that there is a port that is open by default – the port for the remote desktop connection – and we can use it for our ping request:

tcpping 10.10.0.4:3389

That already did the job for me:

If you want to ping your client, then you need to establish a VPN connection from your client to the Azure network:

Connect your client to the virtual network

Another way to troubleshoot your connection is to connect your client via VPN to the Azure virtual network. You need to upload a certificate and use it to connect to the virtual network. If you don’t have a certificate, you can create a self-signed certificate. This process is very well described here:
https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-howto-point-to-site-resource-manager-portal

Execute a webrequest from your web app

Another way to test the connectivity is to execute a web request to one of your servers or your client. I downloaded nginx for the test and started it on my client. The client was connected to the Azure virtual network (VPN). The web app was an API app with Swagger and my TestController class had a piece of code which executes a webrequest to an address that I can define as parameter:

        [Route("test/webrequest/{address}")]
        [HttpPost]
        public async Task<string> GetWebRequest(string address)
        {
            var client = new HttpClient();
            var response = await client.GetAsync(address);
            return await response.Content.ReadAsStringAsync();
        }

I added the url of my webserver with a slash at the end (important because without the slash, swagger has issues to read the whole address) – e.g. http://10.10.0.133/. As a result, I got the html code of the nginx default homepage which is enough for me to know that it works.

Another way is to use kudu console and the curl command:
curl http://10.10.0.133

Use private address space

I once got the message “A non-recoverable error occurred during a database lookup“. I got this error when I tried to use tcpping (kudu console) or others to connect to a resource in my virtual network. The reason for it was, that I used 172.100.0.0/24 as address space for the point-to-site configuration. This configuration is possible and allowed and it works if you have an App Service Environment and also if you connect your client via VPN. But it does not work if you connect an App Service (Web App, API App, …) to the virtual network.
If you look at the virtual network integration, everything seems fine. But if you look into the point-to-site configuration, you can see that there is no allocated IP address, although the app service is connected to the virtual network.

Fix this by using a private address space which is or is inside of one of these:

  • 10.0.0.0/8 (10.0.0.0 – 10.255.255.255)
  • 172.16.0.0/12 (172.16.0.0 – 172.31.255.255)
  • 192.168.0.0/16 (192.168.0.0 – 192.168.255.255)

Additional information

VPN Gateway FAQ: https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-vpn-faq
Integrate your app with an Azure Virtual Network: https://docs.microsoft.com/en-us/azure/app-service-web/web-sites-integrate-with-vnet

9 comments

  1. Oliver says:

    Hello there, Great blog article!

    I’ve come at things from a different angle and have already established my on-prem VPN link to my VNET. Now im having trouble joining my App Services into that VNET.

    Have you actually tried this pattern and had it fully working where the on-prem VNET and the App Servces are both connecting to the same Virtual Network Gateway? Because it looks to me that once a VNG has been assigned a Site-To-Site connection to access on-prem resources, it can’t be used to connect to host point-to-site App Service Connections (as your diagram would indicate) ?

    • Armin Reiter says:

      Hello Oliver,

      thanks!
      Yes, I used the configuration that I described in this blog post. I have a site-to-site VPN from my on-premise network to the Azure virtual network (via virtual network gateway) and I use the same virtual network gateway to connect my app services (and also one of my clients for testing purposes) to the virtual network. With this configuration, my app service is able to read data from a database server in my on-premise network. This configuration is still up and running.

      What does the point-to-site configuration screen show? Are you able to configure the address pool for point-to-site connections?

      For the sake of completeness: As I know, there is just one thing in my blog post which is no longer valid: The connection from a logic app to the virtual network gateway is no longer possible. Previously you could establish a connection from a logic app to a virtual network because it was possible to host a logic app inside of an app service – this is no longer possible.

  2. cellou says:

    Hi,

    this is the best article I have come by on this topic. Azure has lot of capabilities but the documentation is not always easy to follow. Thanks for this good article.

    I am trying to do a similar setup where a web app is connecting to a virtual network using point-to-site and the virtual network is connect to on premise via site-to-site.

    I want the web app to access on premise resources however when I try to ping (using kudo console) my on prem private IP am not getting through. I can ping a VM that is in my subnet1 using the VM private IP, so i assume my point-to-site is ok.

    In terms of setup, I have the standards subnet1 and gateway subnet. My on premise network is configured to connect to subnet 1.

    My vpn connection on the virtual network gateway status shows “succeeded” and “connecting” back and forth.

    Would mind explaining how your VPN (site-to-site) is configured?

    • Armin Reiter says:

      Hi cellou,

      if the status is always switching between connecting and succeeded, than there is an issue with the site-to-site connection. The status “succeeded” just says that the creation of the connection was successful – but it doesn’t say anything about the connection itself – so, if the connection is established or not.
      If the connection is established, the status switches to “Connected” – then everything’s fine. I had the same issue some time ago and it was a configuration issue at the VPN device. There is a documentation on how to configure the different vpn devices for Azure:
      https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-about-vpn-devices
      We tried it with the settings mentioned there and also checked the website of our VPN device vendor. After a few trial and errors, the connection worked.

  3. Ganu Anupama says:

    Hi armin,
    Thanks , this is really great. I have tried to now add my azure web app to a VNET and got the VNET configured. I have to connect my webapp to a Virtual machine which is in another VNET.
    I tried to a VNET peering and it shows the peering is successful and connected.
    However the tcpping to the VM doesnt go through. I checked the NSG as well and it looks fine.
    Am I missing some thing here..

    • Armin Reiter says:

      Hi Ganu,
      ping is per default disabled by the VM firewall (if you use a windows VM). So probably that’s the issue? Are you able to ping from the VM to the web app/a VM in the other vnet?

  4. Ganu Anupama says:

    Hi Armin,
    I found the solution – I had to also add the target VM private IP range in the Web App -App Service plan -Networking-IP ADDRESSES ROUTED TO VNET .
    However I noticed that after integrating with a existing VNET(Which has P2S and also Route based and to mention the VPN has been mapped also with DNS IP), the connection to Azure SQL PaaS was not getting through. There are no overlapping IP address and verified the Private address space with in the 10.0.0.0/8 (10.0.0.0 – 10.255.255.255).
    Figured out that this DNS in the integrated VNET was strangely not allowing the connection to azure SQL(PaaS), probably it could not resolve. However the VMs which are inside the VNET seems to work fine.
    Not sure why the Webapp integrated to this VNET would behave differently.

  5. Andrew Hornsby says:

    We kept getting this error when connecting the App Service to the vnet:

    Adding network XXXX-vnet to web app XXXX-app failed.: Legacy Cmak generation is not supported for gateway id /subscriptions/XXXXXXXXXX/resourceGroups/connection/providers/Microsoft.Network/virtualNetworkGateways/XXXX-vng when vpn client protocol IkeV2 is configured. Please use vpn profile package option instead.

    The network would show as connected in the portal, but we had no connectivity using tcpping.

    We fixed this on the “Virtual Network Gateway / Point-to-site configuration” screen. There is now a section Tunnel type with options of “SSL VPN” and “IKEv2 VPN”. Both of these are selected by default. Remove the “IKEv2 VPN” option and save. Then disconnect your app service from the VNET and then reconnect it and you shouldn’t get the error anymore, and the connectivity works.

    Wasted a few hours on this so I hope it helps someone!

Leave a Reply

Your email address will not be published. Required fields are marked *