I saw a question yesterday about deploying a WebApp on Azure App Service with Application Insights using an ARM template, and thought that would make for a good sample.

The sample ARM template can be found here as a Visual Studio 2017 project.

Creating both the WebApp and the Application Insights resources independently is no problem and should be relatively straight forward for anyone familiar with ARM. However, creating them fully integrated takes just a little bit more work.

Creating the Application Insights Resource

The first step we want to take when creating the template should be to create the AppInsights resource. If you use the Visual Studio wizard for creating an ARM template, you’ll notice that it does this backwards: It forces the AppInsights resource to be dependent on the WebApp being created.

However, this is not necessary, and in fact we want to do it the other way around. In just a moment, it will become obvious why.

So let’s create the Application Insights resource:

{
    "apiVersion": "2014-04-01",
    "name": "[parameters('appInsightsName')]",
    "type": "Microsoft.Insights/components",
    "location": "East US",
    "tags": {
        "[concat('hidden-link:', resourceGroup().id, '/providers/Microsoft.Web/sites/', parameters('webSiteName'))]": "Resource",
        "displayName": "AppInsightsComponent"
    },
    "properties": {
        "applicationId": "[parameters('appInsightsName')]"
    }
}

Here we’re creating new resource of type microsoft.insights/components. The only interesting bit is the tags: Notice that we add a new tag with the name matching the resource id of the WebApp we’re going to create. We can do this even if the WebApp has not been created yet, because we already know what the resource ID is going to look like, and also because the platform will not validate that this represents a valid resource.

The reason we add this tag, is that this creates the link between the WebApp and Application Insights resources. This allows the portal experience to work so that when you navigate to the Application Insights option in the WebApp left-side menu, it shows you the data from the right AppInsights resource.

Creating the WebApp

The second step is creating the App Service Plan and the Web App. There are plenty of good examples of this already, so I won’t go into all the details. There are, however, three interesting aspects I want to highlight.

Setting the right order

We want to make sure that the WebApp is created after the AppInsights resource, which we do by adding an explicit dependency next to the ASP:

"dependsOn": [
    "[resourceId('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]",
    "[resourceId('microsoft.insights/components/', parameters('appInsightsName'))]"
],

The reason we want to do this is that we want to capture the InstrumentationKey for the brand new AppInsights resource, and create the APPINSIGHTS_INSTRUMENTATIONKEY appSetting:

"resources": [
    {
        "apiVersion": "2015-08-01",
        "name": "appsettings",
        "type": "config",
        "dependsOn": [
            "[resourceId('Microsoft.Web/Sites', parameters('webSiteName'))]"
        ],
        "properties": {
            "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(concat('microsoft.insights/components/', parameters('appInsightsName'))).InstrumentationKey]"
        }
    },
    ...
}

Adding the Application Insights site extension

If our WebApp is going to host a .NET Application, we also want to make sure that the Application Insights site extension is deployed in Kudu for our app. This adds the necessary profiler so that we get full dependency traces.

We can do this with yet another nested resource in our ARM template:

{
    "apiVersion": "2015-08-01",
    "name": "Microsoft.ApplicationInsights.AzureWebSites",
    "type": "siteextensions",
    "dependsOn": [
        "[resourceId('Microsoft.Web/Sites', parameters('webSiteName'))]"
    ],
    "properties": {
    }
}

Conclusion

This sample shows how to deploy a full AppServicePlan, WebApp, and AppInsights resources so that we get the full data collection and portal experience, using ARM templates. I tried to keep the template as minimal and simple as possible.

Hope you find it useful.


Tomas Restrepo

Software developer located in Colombia.