Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure Resource Template Dependencies / Application Insights

I have a chicken and egg problem deploying Application Insights with my web application to Azure. In the ARM template, the Application Insights module is dependent upon the web site for the application id (see dependencies in the ARM templates below). On the other hand, in order to fully instrument the web application, I need the instrumentation key from the Application Insights Module. How does one get around this?

Application Insights View From the Portal

Application Insights module in the portal

ARM Template for Web App

Web App ARM Template

ARM Template for Application Insights

app insights arm template

like image 590
Brett Avatar asked Jun 01 '16 13:06

Brett


People also ask

What are dependencies in Azure application insights?

Dependency Tracking in Azure Application Insights. A dependency is an external component that is called by your app. It's typically a service called using HTTP, or a database, or a file system.

Are there any sample Azure Resource Manager templates for application insights?

Thank you. This article includes sample Azure Resource Manager templates to deploy and configure classic Application Insights resources and the new preview workspace-based Application Insights resources. Each sample includes a template file and a parameters file with sample values to provide to the template.

How do I use application insights in azure?

In the Azure portal, you can apply powerful analytics and search tools to the raw data. The following diagram shows how Application Insights instrumentation in an app sends telemetry to an Application Insights resource. There are several ways to get started with Application Insights.

How to deploy application insight resource to a web app?

To deploy application insight resource, we would need to use resource type microsoft.insights/components. We can use something like below code: Do notice that we add a new tag with the name matching the resource id of the web app that we’re going to create.


2 Answers

The solution is to have the connection strings and app settings created as nested child resources of the web site. By using the child resource strategy, one can then make the appsettings dependent upon both the web site and application insights. This allows provisioning to occur in the following order:

  1. Web Site
  2. Application Insights
  3. Web Site config / appsettings

The following two answers were helpful. The first one illustrates how to pull the instrumentation key. The second one illustrates how to nest app settings and connection strings as child resources of the web site.

How to pull the instrumentation key

How to nest app settings as child resources

Here is my final template:

{
  "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "webSiteName": {
      "type": "string"
    },
    "aadTenant": {
      "type": "string"
    },
    "aadAudience": {
      "type": "string"
    },
    "endpoints": {
      "type": "string",
      "defaultValue": "n/a"
    },
    "apiEndpoint": {
      "type": "string",
      "defaultValue": "n/a"
    },
    "sqlConnStrName": {
      "type": "string"
    },
    "sqlConnStrValue": {
      "type": "string"
    },
    "skuName": {
      "type": "string",
      "defaultValue": "F1",
      "allowedValues": [
        "F1",
        "D1",
        "B1",
        "B2",
        "B3",
        "S1",
        "S2",
        "S3",
        "P1",
        "P2",
        "P3",
        "P4"
      ],
      "metadata": {
        "description": "Describes plan's pricing tier and instance size. Check details at https://azure.microsoft.com/en-us/pricing/details/app-service/"
      }
    },
    "skuCapacity": {
      "type": "int",
      "defaultValue": 1,
      "minValue": 1,
      "metadata": {
        "description": "Describes plan's instance count"
      }
    }
  },
  "variables": {
    "hostingPlanName": "[concat(parameters('webSiteName'), '-hostingplan')]"
  },
  "resources": [
    {
      "apiVersion": "2015-08-01",
      "name": "[variables('hostingPlanName')]",
      "type": "Microsoft.Web/serverfarms",
      "location": "[resourceGroup().location]",
      "tags": {
        "displayName": "HostingPlan"
      },
      "sku": {
        "name": "[parameters('skuName')]",
        "capacity": "[parameters('skuCapacity')]"
      },
      "properties": {
        "name": "[variables('hostingPlanName')]"
      }
    },
    {
      "apiVersion": "2015-08-01",
      "name": "[parameters('webSiteName')]",
      "type": "Microsoft.Web/sites",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[variables('hostingPlanName')]"
      ],
      "tags": {
        "[concat('hidden-related:', resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName')))]": "empty",
        "displayName": "Website"
      },
      "properties": {
        "name": "[parameters('webSiteName')]",
        "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]"
      },
      "resources": [
        {
          "apiVersion": "2015-08-01",
          "name": "appsettings",
          "type": "config",
          "dependsOn": [
            "[parameters('webSiteName')]",
            "[concat('AppInsights', parameters('webSiteName'))]"
          ],
          "properties": {
            "ida:Tenant": "[parameters('aadTenant')]",
            "ida:Audience": "[parameters('aadAudience')]",
            "endpoints": "[parameters('endpoints')]",
            "apiEndpoint": "[parameters('apiEndpoint')]",
            "applicationInsightsInstrumentationKey": "[reference(resourceId('Microsoft.Insights/components', concat('AppInsights', parameters('webSiteName'))), '2014-04-01').InstrumentationKey]"
          }
        },
        {
          "apiVersion": "2015-08-01",
          "type": "config",
          "name": "connectionstrings",
          "dependsOn": [
            "[parameters('webSiteName')]"
          ],
          "properties": {
            "[parameters('sqlConnStrName')]": {
              "value": "[parameters('sqlConnStrValue')]",
              "type": "SQLServer"
            }
          }
        },
        {
          "apiVersion": "2015-08-01",
          "name": "logs",
          "type": "config",
          "dependsOn": [
            "[parameters('webSiteName')]"
          ],
          "properties": {
            "applicationLogs": {
              "fileSystem": {
                "level": "Off"
              },
              "azureTableStorage": {
                "level": "Off",
                "sasUrl": null
              },
              "azureBlobStorage": {
                "level": "Information",
                "sasUrl": "TO DO: pass in a SAS Url",
                "retentionInDays": null
              }
            },
            "httpLogs": {
              "fileSystem": {
                "retentionInMb": 40,
                "enabled": true
              }
            },
            "failedRequestsTracing": {
              "enabled": true
            },
            "detailedErrorMessages": {
              "enabled": true
            }
          }
        }
      ]
    },
    {
      "apiVersion": "2014-04-01",
      "name": "[concat(variables('hostingPlanName'), '-', resourceGroup().name)]",
      "type": "Microsoft.Insights/autoscalesettings",
      "location": "[resourceGroup().location]",
      "tags": {
        "[concat('hidden-link:', resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName')))]": "Resource",
        "displayName": "AutoScaleSettings"
      },
      "dependsOn": [
        "[variables('hostingPlanName')]"
      ],
      "properties": {
        "profiles": [
          {
            "name": "Default",
            "capacity": {
              "minimum": 1,
              "maximum": 2,
              "default": 1
            },
            "rules": [
              {
                "metricTrigger": {
                  "metricName": "CpuPercentage",
                  "metricResourceUri": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
                  "timeGrain": "PT1M",
                  "statistic": "Average",
                  "timeWindow": "PT10M",
                  "timeAggregation": "Average",
                  "operator": "GreaterThan",
                  "threshold": 80.0
                },
                "scaleAction": {
                  "direction": "Increase",
                  "type": "ChangeCount",
                  "value": 1,
                  "cooldown": "PT10M"
                }
              },
              {
                "metricTrigger": {
                  "metricName": "CpuPercentage",
                  "metricResourceUri": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
                  "timeGrain": "PT1M",
                  "statistic": "Average",
                  "timeWindow": "PT1H",
                  "timeAggregation": "Average",
                  "operator": "LessThan",
                  "threshold": 60.0
                },
                "scaleAction": {
                  "direction": "Decrease",
                  "type": "ChangeCount",
                  "value": 1,
                  "cooldown": "PT1H"
                }
              }
            ]
          }
        ],
        "enabled": false,
        "name": "[concat(variables('hostingPlanName'), '-', resourceGroup().name)]",
        "targetResourceUri": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]"
      }
    },
    {
      "apiVersion": "2014-04-01",
      "name": "[concat('ServerErrors ', parameters('webSiteName'))]",
      "type": "Microsoft.Insights/alertrules",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[parameters('webSiteName')]"
      ],
      "tags": {
        "[concat('hidden-link:', resourceId('Microsoft.Web/sites', parameters('webSiteName')))]": "Resource",
        "displayName": "ServerErrorsAlertRule"
      },
      "properties": {
        "name": "[concat('ServerErrors ', parameters('webSiteName'))]",
        "description": "[concat(parameters('webSiteName'), ' has some server errors, status code 5xx.')]",
        "isEnabled": true,
        "condition": {
          "odata.type": "Microsoft.Azure.Management.Insights.Models.ThresholdRuleCondition",
          "dataSource": {
            "odata.type": "Microsoft.Azure.Management.Insights.Models.RuleMetricDataSource",
            "resourceUri": "[resourceId('Microsoft.Web/sites', parameters('webSiteName'))]",
            "metricName": "Http5xx"
          },
          "operator": "GreaterThan",
          "threshold": 5.0,
          "windowSize": "PT5M"
        },
        "action": {
          "odata.type": "Microsoft.Azure.Management.Insights.Models.RuleEmailAction",
          "sendToServiceOwners": true,
          "customEmails": ["[email protected]"]
        }
      }
    },
    {
      "apiVersion": "2014-04-01",
      "name": "[concat('ForbiddenRequests ', parameters('webSiteName'))]",
      "type": "Microsoft.Insights/alertrules",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[parameters('webSiteName')]"
      ],
      "tags": {
        "[concat('hidden-link:', resourceId('Microsoft.Web/sites', parameters('webSiteName')))]": "Resource",
        "displayName": "ForbiddenRequestsAlertRule"
      },
      "properties": {
        "name": "[concat('ForbiddenRequests ', parameters('webSiteName'))]",
        "description": "[concat(parameters('webSiteName'), ' has some requests that are forbidden, status code 403.')]",
        "isEnabled": true,
        "condition": {
          "odata.type": "Microsoft.Azure.Management.Insights.Models.ThresholdRuleCondition",
          "dataSource": {
            "odata.type": "Microsoft.Azure.Management.Insights.Models.RuleMetricDataSource",
            "resourceUri": "[resourceId('Microsoft.Web/sites', parameters('webSiteName'))]",
            "metricName": "Http403"
          },
          "operator": "GreaterThan",
          "threshold": 5,
          "windowSize": "PT5M"
        },
        "action": {
          "odata.type": "Microsoft.Azure.Management.Insights.Models.RuleEmailAction",
          "sendToServiceOwners": true,
          "customEmails": [ ]
        }
      }
    },
    {
      "apiVersion": "2014-04-01",
      "name": "[concat('CPUHigh ', variables('hostingPlanName'))]",
      "type": "Microsoft.Insights/alertrules",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[variables('hostingPlanName')]"
      ],
      "tags": {
        "[concat('hidden-link:', resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName')))]": "Resource",
        "displayName": "CPUHighAlertRule"
      },
      "properties": {
        "name": "[concat('CPUHigh ', variables('hostingPlanName'))]",
        "description": "[concat('The average CPU is high across all the instances of ', variables('hostingPlanName'))]",
        "isEnabled": false,
        "condition": {
          "odata.type": "Microsoft.Azure.Management.Insights.Models.ThresholdRuleCondition",
          "dataSource": {
            "odata.type": "Microsoft.Azure.Management.Insights.Models.RuleMetricDataSource",
            "resourceUri": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
            "metricName": "CpuPercentage"
          },
          "operator": "GreaterThan",
          "threshold": 90,
          "windowSize": "PT15M"
        },
        "action": {
          "odata.type": "Microsoft.Azure.Management.Insights.Models.RuleEmailAction",
          "sendToServiceOwners": true,
          "customEmails": [ ]
        }
      }
    },
    {
      "apiVersion": "2014-04-01",
      "name": "[concat('LongHttpQueue ', variables('hostingPlanName'))]",
      "type": "Microsoft.Insights/alertrules",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[variables('hostingPlanName')]"
      ],
      "tags": {
        "[concat('hidden-link:', resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName')))]": "Resource",
        "displayName": "AutoScaleSettings"
      },
      "properties": {
        "name": "[concat('LongHttpQueue ', variables('hostingPlanName'))]",
        "description": "[concat('The HTTP queue for the instances of ', variables('hostingPlanName'), ' has a large number of pending requests.')]",
        "isEnabled": false,
        "condition": {
          "odata.type": "Microsoft.Azure.Management.Insights.Models.ThresholdRuleCondition",
          "dataSource": {
            "odata.type": "Microsoft.Azure.Management.Insights.Models.RuleMetricDataSource",
            "resourceUri": "[concat(resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', variables('hostingPlanName'))]",
            "metricName": "HttpQueueLength"
          },
          "operator": "GreaterThan",
          "threshold": 100.0,
          "windowSize": "PT5M"
        },
        "action": {
          "odata.type": "Microsoft.Azure.Management.Insights.Models.RuleEmailAction",
          "sendToServiceOwners": true,
          "customEmails": [ ]
        }
      }
    },
    {
      "apiVersion": "2014-04-01",
      "name": "[concat('AppInsights', parameters('webSiteName'))]",
      "type": "Microsoft.Insights/components",
      "location": "Central US",
      "dependsOn": [
        "[parameters('webSiteName')]"
      ],
      "tags": {
        "[concat('hidden-link:', resourceId('Microsoft.Web/sites', parameters('webSiteName')))]": "Resource",
        "displayName": "AppInsightsComponent"
      },
      "properties": {
        "ApplicationId": "[parameters('webSiteName')]"
      }
    }
  ],
  "outputs": {
    "siteUri": {
      "type": "string",
      "value": "[reference(concat('Microsoft.Web/sites/', parameters('webSiteName')), '2015-08-01').hostnames[0]]"
    }
  }

}
like image 56
Brett Avatar answered Oct 12 '22 10:10

Brett


Alternative and updated answer (2020/03): do what the Azure Portal UX does (can be viewed via "Download template" at a last step of webapp creation).

For application insights resource, you don't necessarily need to wait for website resource to be created. According to applicationInsights ARM the website.Name is used to applicaitonInsights.properties.ApplicationId. Since you are creating both at the same time, you can pass the name value both to ApplicationInsights and website resources from input:

{
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "subscriptionId": {
            "type": "string"
        },
        "name": {
            "type": "string"
        },
        "location": {
            "type": "string"
        },
        "hostingEnvironment": {
            "type": "string"
        },
        "hostingPlanName": {
            "type": "string"
        },
        "serverFarmResourceGroup": {
            "type": "string"
        },
        "alwaysOn": {
            "type": "bool"
        },
        "sku": {
            "type": "string"
        },
        "skuCode": {
            "type": "string"
        },
        "workerSize": {
            "type": "string"
        },
        "workerSizeId": {
            "type": "string"
        },
        "numberOfWorkers": {
            "type": "string"
        },
        "currentStack": {
            "type": "string"
        },
        "netFrameworkVersion": {
            "type": "string"
        }
    },
    "resources": [
        {
            "apiVersion": "2018-11-01",
            "name": "[parameters('name')]",
            "type": "Microsoft.Web/sites",
            "location": "[parameters('location')]",
            "tags": {},
            "dependsOn": [
                "microsoft.insights/components/testapp01",
                "[concat('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]"
            ],
            "properties": {
                "name": "[parameters('name')]",
                "siteConfig": {
                    "appSettings": [
                        {
                            "name": "APPINSIGHTS_INSTRUMENTATIONKEY",
                            "value": "[reference('microsoft.insights/components/testapp01', '2015-05-01').InstrumentationKey]"
                        },
                        {
                            "name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
                            "value": "[reference('microsoft.insights/components/testapp01', '2015-05-01').ConnectionString]"
                        },
                        {
                            "name": "ApplicationInsightsAgent_EXTENSION_VERSION",
                            "value": "~2"
                        }
                    ],
                    "metadata": [
                        {
                            "name": "CURRENT_STACK",
                            "value": "[parameters('currentStack')]"
                        }
                    ],
                    "netFrameworkVersion": "[parameters('netFrameworkVersion')]",
                    "alwaysOn": "[parameters('alwaysOn')]"
                },
                "serverFarmId": "[concat('/subscriptions/', parameters('subscriptionId'),'/resourcegroups/', parameters('serverFarmResourceGroup'), '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]",
                "hostingEnvironment": "[parameters('hostingEnvironment')]",
                "clientAffinityEnabled": true
            }
        },
        {
            "apiVersion": "2018-11-01",
            "name": "[parameters('hostingPlanName')]",
            "type": "Microsoft.Web/serverfarms",
            "location": "[parameters('location')]",
            "kind": "",
            "tags": {},
            "dependsOn": [],
            "properties": {
                "name": "[parameters('hostingPlanName')]",
                "workerSize": "[parameters('workerSize')]",
                "workerSizeId": "[parameters('workerSizeId')]",
                "numberOfWorkers": "[parameters('numberOfWorkers')]",
                "hostingEnvironment": "[parameters('hostingEnvironment')]"
            },
            "sku": {
                "Tier": "[parameters('sku')]",
                "Name": "[parameters('skuCode')]"
            }
        },
        {
            "apiVersion": "2015-05-01",
            "name": "testapp01",
            "type": "microsoft.insights/components",
            "location": "centralus",
            "tags": {},
            "properties": {
                "ApplicationId": "[parameters('name')]",
                "Request_Source": "IbizaWebAppExtensionCreate"
            }
        }
    ]
}

The order of creation will be following:

  1. Application Insights resource
  2. App Service webapp
like image 34
Mikl X Avatar answered Oct 12 '22 11:10

Mikl X