Vnet Integration for Your App Service

It’s always a good idea to secure the resources in your Azure subscriptions. One way to do this is by using virtual networks. In a lot of cases, you will put SQL Azure servers, storage accounts and, other services in a virtual network. This will make sure the services can’t be accessed from the public internet unless you explicitly say so.
There are many more advantages to putting services in a virtual network, which I won’t be covering in this post.
This post is on how to integrate an App Service to a virtual network.

The different VNet integration types

At this time, there are 2 types of VNet integration for App Services. They are called ‘Regional VNet Integration’ and ‘Gateway-required VNet Integration

If you’re running a relatively simple setup, located in a single region, and don’t require a fancy networking setup, it’s probably a good idea to go with the Regional VNet Integration. This one is rather easy to set up and manage.
With this VNet integration, you can still use NSGs (Network Security Groups), route tables, private endpoints, ExpressRoute, and connect to resources in the same region you’re app is located in.

If there’s a need to connect to one or more VNets in another region, the Gateway-required VNet Integration is the way to go. With this integration your service plan can connect to multiple VNets (each app can only connect to a single one), you can manage your DNS and get to create a point-to-site VPN between the different VNets. This is a bit overkill for most scenarios I’m seeing, but if you’re at a large customer or going global, it makes sense to go with this option.

Integrate your App Service with a VNet

From the Portal

It’s not hard to add the VNet integration in the portal. Over here I’m assuming you already have a VNet at your disposal.

From the ‘Networking’-blade you can choose the option ‘VNet Integration’ vnet integration option

From there you’re able to add the VNet you want to integrate with. VNet Configuration

After clicking it you’ll see the available virtual networks & subnets to connect with. Connect with virtual network

It only takes a couple of seconds to set up the VNet Integration for the App Service. Afterward, you’ll get to see something similar to the picture below. VNet integration set up

Easy, right?

From within an ARM template

Now that you’ve set up the integration, it’s time to store this inside your ARM template. Remember, infrastructure as code is a good idea!

What I did was press the ‘Export Template’ and go on from there. This is the relevant piece of JSON I got.

{
    "type": "Microsoft.Web/sites/virtualNetworkConnections",
    "apiVersion": "2018-11-01",
    "name": "[concat(parameters('mySiteName'), '/c36431b1-fa25-493f-a14f-52adadf77ac0_janv-secureapi-app-subnet')]",
    "location": "West Europe",
    "dependsOn": [
        "[resourceId('Microsoft.Web/sites', parameters('mySiteName'))]"
    ],
    "properties": {
        "vnetResourceId": "[concat(parameters('virtualNetworks_janv_secureapi_backend_network_externalid'), '/subnets/janv-secureapi-app-subnet')]",
        "isSwift": true
    }
}

It matches up with my expectations from the ARM template reference site.

However, this is NOT what you need for a Regional VNet integration, like I had set up from within the portal. The above piece of JSON is a small part of the Gateway-required VNet integration!
When trying to deploy this resource you’ll be confronted with a message stating

Swift network cannot be modified with this API call. Please use call /networkConfig/VirtualNetwork

After having tried out a couple of combinations, searched through the documentation, and did some other stuff (proof!), I finally found a Stack Overflow post which helped me out. The post ARM Template for to configure App Services with new VNet Integration feature?, along with a linked GitHub issue is all the information you need.
To create a Regional VNet Integration the ’new’ virtualNetwork sub-resource has to be used. The necessary JSON looks like this.

{
      "name": "[concat(variables('nameOfYourAppServiceInstance'), '/virtualNetwork')]",
      "type": "Microsoft.Web/sites/config",
      "apiVersion": "2018-02-01",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[resourceId('Microsoft.Web/sites', variables('nameOfYourAppServiceInstance'))]",
        "[resourceId('Microsoft.Network/virtualNetworks/', variables('nameOfTheVirtualNetwork'))]"
      ],
      "properties":
      {
        "subnetResourceId": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('nameOfTheVirtualNetwork'), variables('nameOfTheSubnetYouWantToIntegrateWith'))]",
        "swiftSupported": true
      }
    },

It’s too bad this sub-resource isn’t mentioned, yet, in the ARM template reference docs. That would have saved me a lot of time. App Service reference docs config node

If you’re interested, you can find the full ARM template in my GitHub repository (direct link to the correct version of the template) where I’m continuing my work securing my apps using the Azure services provided to me.


Share