title: Automate Azure Application Insights with PowerShell | Microsoft Docs description: Automate creating resource, alert, and availability tests in PowerShell using an Azure Resource Manager template. services: application-insights documentationcenter: '' author: mrbullwinkle manager: carmonm
ms.assetid: 9f73b87f-be63-4847-88c8-368543acad8b ms.service: application-insights ms.workload: tbd ms.tgt_pltfrm: ibiza ms.devlang: na ms.topic: article ms.date: 04/02/2017 ms.author: mbullwin
This article shows you how to automate the creation and update of Application Insights resources automatically by using Azure Resource Management. You might, for example, do so as part of a build process. Along with the basic Application Insights resource, you can create availability web tests, set up alerts, set the pricing scheme, and create other Azure resources.
The key to creating these resources is JSON templates for Azure Resource Manager. In a nutshell, the procedure is: download the JSON definitions of existing resources; parameterize certain values such as names; and then run the template whenever you want to create a new resource. You can package several resources together, to create them all in one go - for example, an app monitor with availability tests, alerts, and storage for continuous export. There are some subtleties to some of the parameterizations, which we'll explain here.
If you haven't used PowerShell with your Azure subscription before:
Install the Azure Powershell module on the machine where you want to run the scripts:
- Install Microsoft Web Platform Installer (v5 or higher).
- Use it to install Microsoft Azure Powershell.
Create a new .json file - let's call it template1.json
in this example. Copy this content into it:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appName": {
"type": "string",
"metadata": {
"description": "Enter the application name."
}
},
"appType": {
"type": "string",
"defaultValue": "web",
"allowedValues": [
"web",
"java",
"HockeyAppBridge",
"other"
],
"metadata": {
"description": "Enter the application type."
}
},
"appLocation": {
"type": "string",
"defaultValue": "East US",
"allowedValues": [
"South Central US",
"West Europe",
"East US",
"North Europe"
],
"metadata": {
"description": "Enter the application location."
}
},
"priceCode": {
"type": "int",
"defaultValue": 1,
"allowedValues": [
1,
2
],
"metadata": {
"description": "1 = Basic, 2 = Enterprise"
}
},
"dailyQuota": {
"type": "int",
"defaultValue": 100,
"minValue": 1,
"metadata": {
"description": "Enter daily quota in GB."
}
},
"dailyQuotaResetTime": {
"type": "int",
"defaultValue": 24,
"metadata": {
"description": "Enter daily quota reset hour in UTC (0 to 23). Values outside the range will get a random reset hour."
}
},
"warningThreshold": {
"type": "int",
"defaultValue": 90,
"minValue": 1,
"maxValue": 100,
"metadata": {
"description": "Enter the % value of daily quota after which warning mail to be sent. "
}
}
},
"variables": {
"priceArray": [
"Basic",
"Application Insights Enterprise"
],
"pricePlan": "[take(variables('priceArray'),parameters('priceCode'))]",
"billingplan": "[concat(parameters('appName'),'/', variables('pricePlan')[0])]"
},
"resources": [
{
"type": "microsoft.insights/components",
"kind": "[parameters('appType')]",
"name": "[parameters('appName')]",
"apiVersion": "2014-04-01",
"location": "[parameters('appLocation')]",
"tags": {},
"properties": {
"ApplicationId": "[parameters('appName')]"
},
"dependsOn": []
},
{
"name": "[variables('billingplan')]",
"type": "microsoft.insights/components/CurrentBillingFeatures",
"location": "[parameters('appLocation')]",
"apiVersion": "2015-05-01",
"dependsOn": [
"[resourceId('microsoft.insights/components', parameters('appName'))]"
],
"properties": {
"CurrentBillingFeatures": "[variables('pricePlan')]",
"DataVolumeCap": {
"Cap": "[parameters('dailyQuota')]",
"WarningThreshold": "[parameters('warningThreshold')]",
"ResetTime": "[parameters('dailyQuotaResetTime')]"
}
}
}
]
}
-
In PowerShell, sign in to Azure:
Login-AzureRmAccount
-
Run a command like this:
New-AzureRmResourceGroupDeployment -ResourceGroupName Fabrikam ` -TemplateFile .\template1.json ` -appName myNewApp
-ResourceGroupName
is the group where you want to create the new resources.-TemplateFile
must occur before the custom parameters.-appName
The name of the resource to create.
You can add other parameters - you'll find their descriptions in the parameters section of the template.
After creating an application resource, you'll want the instrumentation key:
$resource = Find-AzureRmResource -ResourceNameEquals "<YOUR APP NAME>" -ResourceType "Microsoft.Insights/components"
$details = Get-AzureRmResource -ResourceId $resource.ResourceId
$ikey = $details.Properties.InstrumentationKey
You can set the price plan.
To create an app resource with the Enterprise price plan, using the template above:
New-AzureRmResourceGroupDeployment -ResourceGroupName Fabrikam `
-TemplateFile .\template1.json `
-priceCode 2 `
-appName myNewApp
priceCode | plan |
---|---|
1 | Basic |
2 | Enterprise |
- If you only want to use the default Basic price plan, you can omit the CurrentBillingFeatures resource from the template.
- If you want to change the price plan after the component resource has been created, you can use a template that omits the "microsoft.insights/components" resource. Also, omit the
dependsOn
node from the billing resource.
To verify the updated price plan, look at the "Features+pricing" blade in the browser. Refresh the browser view to make sure you see the latest state.
To set up a metric alert at the same time as your app resource, merge code like this into the template file:
{
parameters: { ... // existing parameters ...
"responseTime": {
"type": "int",
"defaultValue": 3,
"minValue": 1,
"metadata": {
"description": "Enter response time threshold in seconds."
}
},
variables: { ... // existing variables ...
// Alert names must be unique within resource group.
"responseAlertName": "[concat('ResponseTime-', toLower(parameters('appName')))]"
},
resources: { ... // existing resources ...
{
//
// Metric alert on response time
//
"name": "[variables('responseAlertName')]",
"type": "Microsoft.Insights/alertrules",
"apiVersion": "2014-04-01",
"location": "[parameters('appLocation')]",
// Ensure this resource is created after the app resource:
"dependsOn": [
"[resourceId('Microsoft.Insights/components', parameters('appName'))]"
],
"tags": {
"[concat('hidden-link:', resourceId('Microsoft.Insights/components', parameters('appName')))]": "Resource"
},
"properties": {
"name": "[variables('responseAlertName')]",
"description": "response time alert",
"isEnabled": true,
"condition": {
"$type": "Microsoft.WindowsAzure.Management.Monitoring.Alerts.Models.ThresholdRuleCondition, Microsoft.WindowsAzure.Management.Mon.Client",
"odata.type": "Microsoft.Azure.Management.Insights.Models.ThresholdRuleCondition",
"dataSource": {
"$type": "Microsoft.WindowsAzure.Management.Monitoring.Alerts.Models.RuleMetricDataSource, Microsoft.WindowsAzure.Management.Mon.Client",
"odata.type": "Microsoft.Azure.Management.Insights.Models.RuleMetricDataSource",
"resourceUri": "[resourceId('microsoft.insights/components', parameters('appName'))]",
"metricName": "request.duration"
},
"threshold": "[parameters('responseTime')]", //seconds
"windowSize": "PT15M" // Take action if changed state for 15 minutes
},
"actions": [
{
"$type": "Microsoft.WindowsAzure.Management.Monitoring.Alerts.Models.RuleEmailAction, Microsoft.WindowsAzure.Management.Mon.Client",
"odata.type": "Microsoft.Azure.Management.Insights.Models.RuleEmailAction",
"sendToServiceOwners": true,
"customEmails": []
}
]
}
}
}
When you invoke the template, you can optionally add this parameter:
`-responseTime 2`
You can of course parameterize other fields.
To find out the type names and configuration details of other alert rules, create a rule manually and then inspect it in Azure Resource Manager.
This example is for a ping test (to test a single page).
There are two parts in an availability test: the test itself, and the alert that notifies you of failures.
Merge the following code into the template file that creates the app.
{
parameters: { ... // existing parameters here ...
"pingURL": { "type": "string" },
"pingText": { "type": "string" , defaultValue: ""}
},
variables: { ... // existing variables here ...
"pingTestName":"[concat('PingTest-', toLower(parameters('appName')))]",
"pingAlertRuleName": "[concat('PingAlert-', toLower(parameters('appName')), '-', subscription().subscriptionId)]"
},
resources: { ... // existing resources here ...
{ //
// Availability test: part 1 configures the test
//
"name": "[variables('pingTestName')]",
"type": "Microsoft.Insights/webtests",
"apiVersion": "2014-04-01",
"location": "[parameters('appLocation')]",
// Ensure this is created after the app resource:
"dependsOn": [
"[resourceId('Microsoft.Insights/components', parameters('appName'))]"
],
"tags": {
"[concat('hidden-link:', resourceId('Microsoft.Insights/components', parameters('appName')))]": "Resource"
},
"properties": {
"Name": "[variables('pingTestName')]",
"Description": "Basic ping test",
"Enabled": true,
"Frequency": 900, // 15 minutes
"Timeout": 120, // 2 minutes
"Kind": "ping", // single URL test
"RetryEnabled": true,
"Locations": [
{
"Id": "us-va-ash-azr"
},
{
"Id": "emea-nl-ams-azr"
},
{
"Id": "apac-jp-kaw-edge"
}
],
"Configuration": {
"WebTest": "[concat('<WebTest Name=\"', variables('pingTestName'), '\" Enabled=\"True\" CssProjectStructure=\"\" CssIteration=\"\" Timeout=\"120\" WorkItemIds=\"\" xmlns=\"http://microsoft.com/schemas/VisualStudio/TeamTest/2010\" Description=\"\" CredentialUserName=\"\" CredentialPassword=\"\" PreAuthenticate=\"True\" Proxy=\"default\" StopOnError=\"False\" RecordedResultFile=\"\" ResultsLocale=\"\"> <Items> <Request Method=\"GET\" Version=\"1.1\" Url=\"', parameters('Url'), '\" ThinkTime=\"0\" Timeout=\"300\" ParseDependentRequests=\"True\" FollowRedirects=\"True\" RecordResult=\"True\" Cache=\"False\" ResponseTimeGoal=\"0\" Encoding=\"utf-8\" ExpectedHttpStatusCode=\"200\" ExpectedResponseUrl=\"\" ReportingName=\"\" IgnoreHttpStatusCode=\"False\" /> </Items> <ValidationRules> <ValidationRule Classname=\"Microsoft.VisualStudio.TestTools.WebTesting.Rules.ValidationRuleFindText, Microsoft.VisualStudio.QualityTools.WebTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\" DisplayName=\"Find Text\" Description=\"Verifies the existence of the specified text in the response.\" Level=\"High\" ExectuionOrder=\"BeforeDependents\"> <RuleParameters> <RuleParameter Name=\"FindText\" Value=\"', parameters('pingText'), '\" /> <RuleParameter Name=\"IgnoreCase\" Value=\"False\" /> <RuleParameter Name=\"UseRegularExpression\" Value=\"False\" /> <RuleParameter Name=\"PassIfTextFound\" Value=\"True\" /> </RuleParameters> </ValidationRule> </ValidationRules> </WebTest>')]"
},
"SyntheticMonitorId": "[variables('pingTestName')]"
}
},
{
//
// Availability test: part 2, the alert rule
//
"name": "[variables('pingAlertRuleName')]",
"type": "Microsoft.Insights/alertrules",
"apiVersion": "2014-04-01",
"location": "[parameters('appLocation')]",
"dependsOn": [
"[resourceId('Microsoft.Insights/webtests', variables('pingTestName'))]"
],
"tags": {
"[concat('hidden-link:', resourceId('Microsoft.Insights/components', parameters('appName')))]": "Resource",
"[concat('hidden-link:', resourceId('Microsoft.Insights/webtests', variables('pingTestName')))]": "Resource"
},
"properties": {
"name": "[variables('pingAlertRuleName')]",
"description": "alert for web test",
"isEnabled": true,
"condition": {
"$type": "Microsoft.WindowsAzure.Management.Monitoring.Alerts.Models.LocationThresholdRuleCondition, Microsoft.WindowsAzure.Management.Mon.Client",
"odata.type": "Microsoft.Azure.Management.Insights.Models.LocationThresholdRuleCondition",
"dataSource": {
"$type": "Microsoft.WindowsAzure.Management.Monitoring.Alerts.Models.RuleMetricDataSource, Microsoft.WindowsAzure.Management.Mon.Client",
"odata.type": "Microsoft.Azure.Management.Insights.Models.RuleMetricDataSource",
"resourceUri": "[resourceId('microsoft.insights/webtests', variables('pingTestName'))]",
"metricName": "GSMT_AvRaW"
},
"windowSize": "PT15M", // Take action if changed state for 15 minutes
"failedLocationCount": 2
},
"actions": [
{
"$type": "Microsoft.WindowsAzure.Management.Monitoring.Alerts.Models.RuleEmailAction, Microsoft.WindowsAzure.Management.Mon.Client",
"odata.type": "Microsoft.Azure.Management.Insights.Models.RuleEmailAction",
"sendToServiceOwners": true,
"customEmails": []
}
]
}
}
}
To discover the codes for other test locations, or to automate the creation of more complex web tests, create an example manually and then parameterize the code from Azure Resource Manager.
To automate the creation of any other resource of any kind, create an example manually, and then copy and parameterize its code from Azure Resource Manager.
-
Open Azure Resource Manager. Navigate down through
subscriptions/resourceGroups/<your resource group>/providers/Microsoft.Insights/components
, to your application resource.Components are the basic Application Insights resources for displaying applications. There are separate resources for the associated alert rules and availability web tests.
-
Copy the JSON of the component into the appropriate place in
template1.json
. -
Delete these properties:
id
InstrumentationKey
CreationDate
TenantId
-
Open the webtests and alertrules sections and copy the JSON for individual items into your template. (Don't copy from the webtests or alertrules nodes: go into the items under them.)
Each web test has an associated alert rule, so you have to copy both of them.
You can also include alerts on metrics. Metric names.
-
Insert this line in each resource:
"apiVersion": "2015-05-01",
Now you have to replace the specific names with parameters. To parameterize a template, you write expressions using a set of helper functions.
You can't parameterize just part of a string, so use concat()
to build strings.
Here are examples of the substitutions you'll want to make. There are several occurrences of each substitution. You might need others in your template. These examples use the parameters and variables we defined at the top of the template.
find | replace with |
---|---|
"hidden-link:/subscriptions/.../components/MyAppName" |
"[concat('hidden-link:', resourceId('microsoft.insights/components', parameters('appName')))]" |
"/subscriptions/.../alertrules/myAlertName-myAppName-subsId", |
"[resourceId('Microsoft.Insights/alertrules', variables('alertRuleName'))]", |
"/subscriptions/.../webtests/myTestName-myAppName", |
"[resourceId('Microsoft.Insights/webtests', parameters('webTestName'))]", |
"myWebTest-myAppName" |
"[variables(testName)]"' |
"myTestName-myAppName-subsId" |
"[variables('alertRuleName')]" |
"myAppName" |
"[parameters('appName')]" |
"myappname" (lower case) |
"[toLower(parameters('appName'))]" |
"<WebTest Name=\"myWebTest\" ... Url=\"http://fabrikam.com/home\" ...>" |
[concat('<WebTest Name=\"', parameters('webTestName'), '\" ... Url=\"', parameters('Url'), '\"...>')]" Delete Guid and Id. |
Azure should set up the resources in strict order. To make sure one setup completes before the next begins, add dependency lines:
-
In the availability test resource:
"dependsOn": ["[resourceId('Microsoft.Insights/components', parameters('appName'))]"],
-
In the alert resource for an availability test:
"dependsOn": ["[resourceId('Microsoft.Insights/webtests', variables('testName'))]"],
Other automation articles:
- Create an Application Insights resource - quick method without using a template.
- Set up Alerts
- Create web tests
- Send Azure Diagnostics to Application Insights
- Deploy to Azure from GitHub
- Create release annotations