Create Azure Metric Alerts

The azure-native:monitor:MetricAlert resource, part of the Pulumi Azure Native provider, defines metric alert rules that evaluate Azure Monitor metrics and trigger actions when conditions are met. This guide focuses on four capabilities: static threshold monitoring across resources, dynamic threshold anomaly detection, dimension-based metric filtering, and Application Insights availability alerts.

Metric alerts reference existing Azure resources and action groups for notifications. The examples are intentionally small. Combine them with your own resource IDs, action groups, and notification targets.

Monitor CPU across multiple VMs with static thresholds

Most monitoring deployments track resource metrics like CPU utilization across a fleet of VMs, alerting when metrics breach predefined values.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const metricAlert = new azure_native.monitor.MetricAlert("metricAlert", {
    actions: [{
        actionGroupId: "/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2",
        webHookProperties: {
            key11: "value11",
            key12: "value12",
        },
    }],
    autoMitigate: true,
    criteria: {
        allOf: [{
            criterionType: "StaticThresholdCriterion",
            dimensions: [],
            metricName: "Percentage CPU",
            metricNamespace: "microsoft.compute/virtualmachines",
            name: "High_CPU_80",
            operator: azure_native.monitor.Operator.GreaterThan,
            threshold: 80.5,
            timeAggregation: azure_native.monitor.AggregationTypeEnum.Average,
        }],
        odataType: "Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria",
    },
    description: "This is the description of the rule1",
    enabled: true,
    evaluationFrequency: "PT1M",
    location: "global",
    resourceGroupName: "gigtest",
    ruleName: "MetricAlertOnMultipleResources",
    scopes: [
        "/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme1",
        "/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme2",
    ],
    severity: 3,
    tags: {},
    targetResourceRegion: "southcentralus",
    targetResourceType: "Microsoft.Compute/virtualMachines",
    windowSize: "PT15M",
});
import pulumi
import pulumi_azure_native as azure_native

metric_alert = azure_native.monitor.MetricAlert("metricAlert",
    actions=[{
        "action_group_id": "/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2",
        "web_hook_properties": {
            "key11": "value11",
            "key12": "value12",
        },
    }],
    auto_mitigate=True,
    criteria={
        "all_of": [{
            "criterion_type": "StaticThresholdCriterion",
            "dimensions": [],
            "metric_name": "Percentage CPU",
            "metric_namespace": "microsoft.compute/virtualmachines",
            "name": "High_CPU_80",
            "operator": azure_native.monitor.Operator.GREATER_THAN,
            "threshold": 80.5,
            "time_aggregation": azure_native.monitor.AggregationTypeEnum.AVERAGE,
        }],
        "odata_type": "Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria",
    },
    description="This is the description of the rule1",
    enabled=True,
    evaluation_frequency="PT1M",
    location="global",
    resource_group_name="gigtest",
    rule_name="MetricAlertOnMultipleResources",
    scopes=[
        "/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme1",
        "/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme2",
    ],
    severity=3,
    tags={},
    target_resource_region="southcentralus",
    target_resource_type="Microsoft.Compute/virtualMachines",
    window_size="PT15M")
package main

import (
	monitor "github.com/pulumi/pulumi-azure-native-sdk/monitor/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := monitor.NewMetricAlert(ctx, "metricAlert", &monitor.MetricAlertArgs{
			Actions: monitor.MetricAlertActionArray{
				&monitor.MetricAlertActionArgs{
					ActionGroupId: pulumi.String("/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2"),
					WebHookProperties: pulumi.StringMap{
						"key11": pulumi.String("value11"),
						"key12": pulumi.String("value12"),
					},
				},
			},
			AutoMitigate: pulumi.Bool(true),
			Criteria: &monitor.MetricAlertMultipleResourceMultipleMetricCriteriaArgs{
				AllOf: pulumi.Array{
					monitor.MetricCriteria{
						CriterionType:   "StaticThresholdCriterion",
						Dimensions:      []monitor.MetricDimension{},
						MetricName:      "Percentage CPU",
						MetricNamespace: "microsoft.compute/virtualmachines",
						Name:            "High_CPU_80",
						Operator:        monitor.OperatorGreaterThan,
						Threshold:       80.5,
						TimeAggregation: monitor.AggregationTypeEnumAverage,
					},
				},
				OdataType: pulumi.String("Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria"),
			},
			Description:         pulumi.String("This is the description of the rule1"),
			Enabled:             pulumi.Bool(true),
			EvaluationFrequency: pulumi.String("PT1M"),
			Location:            pulumi.String("global"),
			ResourceGroupName:   pulumi.String("gigtest"),
			RuleName:            pulumi.String("MetricAlertOnMultipleResources"),
			Scopes: pulumi.StringArray{
				pulumi.String("/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme1"),
				pulumi.String("/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme2"),
			},
			Severity:             pulumi.Int(3),
			Tags:                 pulumi.StringMap{},
			TargetResourceRegion: pulumi.String("southcentralus"),
			TargetResourceType:   pulumi.String("Microsoft.Compute/virtualMachines"),
			WindowSize:           pulumi.String("PT15M"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var metricAlert = new AzureNative.Monitor.MetricAlert("metricAlert", new()
    {
        Actions = new[]
        {
            new AzureNative.Monitor.Inputs.MetricAlertActionArgs
            {
                ActionGroupId = "/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2",
                WebHookProperties = 
                {
                    { "key11", "value11" },
                    { "key12", "value12" },
                },
            },
        },
        AutoMitigate = true,
        Criteria = new AzureNative.Monitor.Inputs.MetricAlertMultipleResourceMultipleMetricCriteriaArgs
        {
            AllOf = new[]
            {
                new AzureNative.Monitor.Inputs.MetricCriteriaArgs
                {
                    CriterionType = "StaticThresholdCriterion",
                    Dimensions = new() { },
                    MetricName = "Percentage CPU",
                    MetricNamespace = "microsoft.compute/virtualmachines",
                    Name = "High_CPU_80",
                    Operator = AzureNative.Monitor.Operator.GreaterThan,
                    Threshold = 80.5,
                    TimeAggregation = AzureNative.Monitor.AggregationTypeEnum.Average,
                },
            },
            OdataType = "Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria",
        },
        Description = "This is the description of the rule1",
        Enabled = true,
        EvaluationFrequency = "PT1M",
        Location = "global",
        ResourceGroupName = "gigtest",
        RuleName = "MetricAlertOnMultipleResources",
        Scopes = new[]
        {
            "/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme1",
            "/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme2",
        },
        Severity = 3,
        Tags = null,
        TargetResourceRegion = "southcentralus",
        TargetResourceType = "Microsoft.Compute/virtualMachines",
        WindowSize = "PT15M",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.monitor.MetricAlert;
import com.pulumi.azurenative.monitor.MetricAlertArgs;
import com.pulumi.azurenative.monitor.inputs.MetricAlertActionArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var metricAlert = new MetricAlert("metricAlert", MetricAlertArgs.builder()
            .actions(MetricAlertActionArgs.builder()
                .actionGroupId("/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2")
                .webHookProperties(Map.ofEntries(
                    Map.entry("key11", "value11"),
                    Map.entry("key12", "value12")
                ))
                .build())
            .autoMitigate(true)
            .criteria(MetricAlertMultipleResourceMultipleMetricCriteriaArgs.builder()
                .allOf(MetricCriteriaArgs.builder()
                    .criterionType("StaticThresholdCriterion")
                    .dimensions()
                    .metricName("Percentage CPU")
                    .metricNamespace("microsoft.compute/virtualmachines")
                    .name("High_CPU_80")
                    .operator("GreaterThan")
                    .threshold(80.5)
                    .timeAggregation("Average")
                    .build())
                .odataType("Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria")
                .build())
            .description("This is the description of the rule1")
            .enabled(true)
            .evaluationFrequency("PT1M")
            .location("global")
            .resourceGroupName("gigtest")
            .ruleName("MetricAlertOnMultipleResources")
            .scopes(            
                "/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme1",
                "/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme2")
            .severity(3)
            .tags(Map.ofEntries(
            ))
            .targetResourceRegion("southcentralus")
            .targetResourceType("Microsoft.Compute/virtualMachines")
            .windowSize("PT15M")
            .build());

    }
}
resources:
  metricAlert:
    type: azure-native:monitor:MetricAlert
    properties:
      actions:
        - actionGroupId: /subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2
          webHookProperties:
            key11: value11
            key12: value12
      autoMitigate: true
      criteria:
        allOf:
          - criterionType: StaticThresholdCriterion
            dimensions: []
            metricName: Percentage CPU
            metricNamespace: microsoft.compute/virtualmachines
            name: High_CPU_80
            operator: GreaterThan
            threshold: 80.5
            timeAggregation: Average
        odataType: Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria
      description: This is the description of the rule1
      enabled: true
      evaluationFrequency: PT1M
      location: global
      resourceGroupName: gigtest
      ruleName: MetricAlertOnMultipleResources
      scopes:
        - /subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme1
        - /subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme2
      severity: 3
      tags: {}
      targetResourceRegion: southcentralus
      targetResourceType: Microsoft.Compute/virtualMachines
      windowSize: PT15M

The criteria property defines evaluation logic. The allOf array contains conditions; here, a single StaticThresholdCriterion checks if average CPU exceeds 80.5%. The scopes property lists VM resource IDs to monitor, while targetResourceType filters to virtual machines. When the threshold breaches, actions trigger notifications via the specified action group. The evaluationFrequency (PT1M) and windowSize (PT15M) control how often Azure checks metrics and over what time period.

Detect anomalies with dynamic thresholds

When baseline behavior varies over time, dynamic thresholds learn normal patterns and alert on deviations rather than fixed values.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const metricAlert = new azure_native.monitor.MetricAlert("metricAlert", {
    actions: [{
        actionGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2",
        webHookProperties: {
            key11: "value11",
            key12: "value12",
        },
    }],
    autoMitigate: true,
    criteria: {
        allOf: [{
            alertSensitivity: azure_native.monitor.DynamicThresholdSensitivity.Medium,
            criterionType: "DynamicThresholdCriterion",
            dimensions: [],
            failingPeriods: {
                minFailingPeriodsToAlert: 4,
                numberOfEvaluationPeriods: 4,
            },
            metricName: "Percentage CPU",
            metricNamespace: "microsoft.compute/virtualmachines",
            name: "High_CPU_80",
            operator: azure_native.monitor.DynamicThresholdOperator.GreaterOrLessThan,
            timeAggregation: azure_native.monitor.AggregationTypeEnum.Average,
        }],
        odataType: "Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria",
    },
    description: "This is the description of the rule1",
    enabled: true,
    evaluationFrequency: "PT1M",
    location: "global",
    resourceGroupName: "gigtest",
    ruleName: "MetricAlertOnMultipleResources",
    scopes: [
        "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme1",
        "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme2",
    ],
    severity: 3,
    tags: {},
    targetResourceRegion: "southcentralus",
    targetResourceType: "Microsoft.Compute/virtualMachines",
    windowSize: "PT15M",
});
import pulumi
import pulumi_azure_native as azure_native

metric_alert = azure_native.monitor.MetricAlert("metricAlert",
    actions=[{
        "action_group_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2",
        "web_hook_properties": {
            "key11": "value11",
            "key12": "value12",
        },
    }],
    auto_mitigate=True,
    criteria={
        "all_of": [{
            "alert_sensitivity": azure_native.monitor.DynamicThresholdSensitivity.MEDIUM,
            "criterion_type": "DynamicThresholdCriterion",
            "dimensions": [],
            "failing_periods": {
                "min_failing_periods_to_alert": 4,
                "number_of_evaluation_periods": 4,
            },
            "metric_name": "Percentage CPU",
            "metric_namespace": "microsoft.compute/virtualmachines",
            "name": "High_CPU_80",
            "operator": azure_native.monitor.DynamicThresholdOperator.GREATER_OR_LESS_THAN,
            "time_aggregation": azure_native.monitor.AggregationTypeEnum.AVERAGE,
        }],
        "odata_type": "Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria",
    },
    description="This is the description of the rule1",
    enabled=True,
    evaluation_frequency="PT1M",
    location="global",
    resource_group_name="gigtest",
    rule_name="MetricAlertOnMultipleResources",
    scopes=[
        "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme1",
        "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme2",
    ],
    severity=3,
    tags={},
    target_resource_region="southcentralus",
    target_resource_type="Microsoft.Compute/virtualMachines",
    window_size="PT15M")
package main

import (
	monitor "github.com/pulumi/pulumi-azure-native-sdk/monitor/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := monitor.NewMetricAlert(ctx, "metricAlert", &monitor.MetricAlertArgs{
			Actions: monitor.MetricAlertActionArray{
				&monitor.MetricAlertActionArgs{
					ActionGroupId: pulumi.String("/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2"),
					WebHookProperties: pulumi.StringMap{
						"key11": pulumi.String("value11"),
						"key12": pulumi.String("value12"),
					},
				},
			},
			AutoMitigate: pulumi.Bool(true),
			Criteria: &monitor.MetricAlertMultipleResourceMultipleMetricCriteriaArgs{
				AllOf: pulumi.Array{
					monitor.DynamicMetricCriteria{
						AlertSensitivity: monitor.DynamicThresholdSensitivityMedium,
						CriterionType:    "DynamicThresholdCriterion",
						Dimensions:       []monitor.MetricDimension{},
						FailingPeriods: monitor.DynamicThresholdFailingPeriods{
							MinFailingPeriodsToAlert:  4,
							NumberOfEvaluationPeriods: 4,
						},
						MetricName:      "Percentage CPU",
						MetricNamespace: "microsoft.compute/virtualmachines",
						Name:            "High_CPU_80",
						Operator:        monitor.DynamicThresholdOperatorGreaterOrLessThan,
						TimeAggregation: monitor.AggregationTypeEnumAverage,
					},
				},
				OdataType: pulumi.String("Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria"),
			},
			Description:         pulumi.String("This is the description of the rule1"),
			Enabled:             pulumi.Bool(true),
			EvaluationFrequency: pulumi.String("PT1M"),
			Location:            pulumi.String("global"),
			ResourceGroupName:   pulumi.String("gigtest"),
			RuleName:            pulumi.String("MetricAlertOnMultipleResources"),
			Scopes: pulumi.StringArray{
				pulumi.String("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme1"),
				pulumi.String("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme2"),
			},
			Severity:             pulumi.Int(3),
			Tags:                 pulumi.StringMap{},
			TargetResourceRegion: pulumi.String("southcentralus"),
			TargetResourceType:   pulumi.String("Microsoft.Compute/virtualMachines"),
			WindowSize:           pulumi.String("PT15M"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var metricAlert = new AzureNative.Monitor.MetricAlert("metricAlert", new()
    {
        Actions = new[]
        {
            new AzureNative.Monitor.Inputs.MetricAlertActionArgs
            {
                ActionGroupId = "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2",
                WebHookProperties = 
                {
                    { "key11", "value11" },
                    { "key12", "value12" },
                },
            },
        },
        AutoMitigate = true,
        Criteria = new AzureNative.Monitor.Inputs.MetricAlertMultipleResourceMultipleMetricCriteriaArgs
        {
            AllOf = new[]
            {
                new AzureNative.Monitor.Inputs.DynamicMetricCriteriaArgs
                {
                    AlertSensitivity = AzureNative.Monitor.DynamicThresholdSensitivity.Medium,
                    CriterionType = "DynamicThresholdCriterion",
                    Dimensions = new() { },
                    FailingPeriods = new AzureNative.Monitor.Inputs.DynamicThresholdFailingPeriodsArgs
                    {
                        MinFailingPeriodsToAlert = 4,
                        NumberOfEvaluationPeriods = 4,
                    },
                    MetricName = "Percentage CPU",
                    MetricNamespace = "microsoft.compute/virtualmachines",
                    Name = "High_CPU_80",
                    Operator = AzureNative.Monitor.DynamicThresholdOperator.GreaterOrLessThan,
                    TimeAggregation = AzureNative.Monitor.AggregationTypeEnum.Average,
                },
            },
            OdataType = "Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria",
        },
        Description = "This is the description of the rule1",
        Enabled = true,
        EvaluationFrequency = "PT1M",
        Location = "global",
        ResourceGroupName = "gigtest",
        RuleName = "MetricAlertOnMultipleResources",
        Scopes = new[]
        {
            "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme1",
            "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme2",
        },
        Severity = 3,
        Tags = null,
        TargetResourceRegion = "southcentralus",
        TargetResourceType = "Microsoft.Compute/virtualMachines",
        WindowSize = "PT15M",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.monitor.MetricAlert;
import com.pulumi.azurenative.monitor.MetricAlertArgs;
import com.pulumi.azurenative.monitor.inputs.MetricAlertActionArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var metricAlert = new MetricAlert("metricAlert", MetricAlertArgs.builder()
            .actions(MetricAlertActionArgs.builder()
                .actionGroupId("/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2")
                .webHookProperties(Map.ofEntries(
                    Map.entry("key11", "value11"),
                    Map.entry("key12", "value12")
                ))
                .build())
            .autoMitigate(true)
            .criteria(MetricAlertMultipleResourceMultipleMetricCriteriaArgs.builder()
                .allOf(DynamicMetricCriteriaArgs.builder()
                    .alertSensitivity("Medium")
                    .criterionType("DynamicThresholdCriterion")
                    .dimensions()
                    .failingPeriods(DynamicThresholdFailingPeriodsArgs.builder()
                        .minFailingPeriodsToAlert(4)
                        .numberOfEvaluationPeriods(4)
                        .build())
                    .metricName("Percentage CPU")
                    .metricNamespace("microsoft.compute/virtualmachines")
                    .name("High_CPU_80")
                    .operator("GreaterOrLessThan")
                    .timeAggregation("Average")
                    .build())
                .odataType("Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria")
                .build())
            .description("This is the description of the rule1")
            .enabled(true)
            .evaluationFrequency("PT1M")
            .location("global")
            .resourceGroupName("gigtest")
            .ruleName("MetricAlertOnMultipleResources")
            .scopes(            
                "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme1",
                "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme2")
            .severity(3)
            .tags(Map.ofEntries(
            ))
            .targetResourceRegion("southcentralus")
            .targetResourceType("Microsoft.Compute/virtualMachines")
            .windowSize("PT15M")
            .build());

    }
}
resources:
  metricAlert:
    type: azure-native:monitor:MetricAlert
    properties:
      actions:
        - actionGroupId: /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2
          webHookProperties:
            key11: value11
            key12: value12
      autoMitigate: true
      criteria:
        allOf:
          - alertSensitivity: Medium
            criterionType: DynamicThresholdCriterion
            dimensions: []
            failingPeriods:
              minFailingPeriodsToAlert: 4
              numberOfEvaluationPeriods: 4
            metricName: Percentage CPU
            metricNamespace: microsoft.compute/virtualmachines
            name: High_CPU_80
            operator: GreaterOrLessThan
            timeAggregation: Average
        odataType: Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria
      description: This is the description of the rule1
      enabled: true
      evaluationFrequency: PT1M
      location: global
      resourceGroupName: gigtest
      ruleName: MetricAlertOnMultipleResources
      scopes:
        - /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme1
        - /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/gigtest/providers/Microsoft.Compute/virtualMachines/gigwadme2
      severity: 3
      tags: {}
      targetResourceRegion: southcentralus
      targetResourceType: Microsoft.Compute/virtualMachines
      windowSize: PT15M

Dynamic thresholds use machine learning to establish baselines. The criterionType switches to DynamicThresholdCriterion, and alertSensitivity (Low, Medium, High) controls how sensitive the model is to deviations. The failingPeriods block requires 4 out of 4 evaluation periods to breach before alerting, reducing false positives. The operator GreaterOrLessThan alerts on deviations in either direction, useful when both spikes and drops matter.

Filter alerts by metric dimensions

Azure metrics often include dimensions like operation name or status code. Dimension filters let you alert on specific slices of metric data.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const metricAlert = new azure_native.monitor.MetricAlert("metricAlert", {
    actions: [{
        actionGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2",
        webHookProperties: {
            key11: "value11",
            key12: "value12",
        },
    }],
    autoMitigate: true,
    criteria: {
        allOf: [{
            criterionType: "StaticThresholdCriterion",
            dimensions: [
                {
                    name: "ActivityName",
                    operator: "Include",
                    values: ["*"],
                },
                {
                    name: "StatusCode",
                    operator: "Include",
                    values: ["200"],
                },
            ],
            metricName: "Availability",
            metricNamespace: "Microsoft.KeyVault/vaults",
            name: "Metric1",
            operator: azure_native.monitor.Operator.GreaterThan,
            threshold: 55,
            timeAggregation: azure_native.monitor.AggregationTypeEnum.Average,
        }],
        odataType: "Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria",
    },
    description: "This is the description of the rule1",
    enabled: true,
    evaluationFrequency: "PT1H",
    location: "global",
    resourceGroupName: "gigtest",
    ruleName: "MetricAlertOnMultipleDimensions",
    scopes: ["/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.KeyVault/vaults/keyVaultResource"],
    severity: 3,
    tags: {},
    windowSize: "P1D",
});
import pulumi
import pulumi_azure_native as azure_native

metric_alert = azure_native.monitor.MetricAlert("metricAlert",
    actions=[{
        "action_group_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2",
        "web_hook_properties": {
            "key11": "value11",
            "key12": "value12",
        },
    }],
    auto_mitigate=True,
    criteria={
        "all_of": [{
            "criterion_type": "StaticThresholdCriterion",
            "dimensions": [
                {
                    "name": "ActivityName",
                    "operator": "Include",
                    "values": ["*"],
                },
                {
                    "name": "StatusCode",
                    "operator": "Include",
                    "values": ["200"],
                },
            ],
            "metric_name": "Availability",
            "metric_namespace": "Microsoft.KeyVault/vaults",
            "name": "Metric1",
            "operator": azure_native.monitor.Operator.GREATER_THAN,
            "threshold": 55,
            "time_aggregation": azure_native.monitor.AggregationTypeEnum.AVERAGE,
        }],
        "odata_type": "Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria",
    },
    description="This is the description of the rule1",
    enabled=True,
    evaluation_frequency="PT1H",
    location="global",
    resource_group_name="gigtest",
    rule_name="MetricAlertOnMultipleDimensions",
    scopes=["/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.KeyVault/vaults/keyVaultResource"],
    severity=3,
    tags={},
    window_size="P1D")
package main

import (
	monitor "github.com/pulumi/pulumi-azure-native-sdk/monitor/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := monitor.NewMetricAlert(ctx, "metricAlert", &monitor.MetricAlertArgs{
			Actions: monitor.MetricAlertActionArray{
				&monitor.MetricAlertActionArgs{
					ActionGroupId: pulumi.String("/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2"),
					WebHookProperties: pulumi.StringMap{
						"key11": pulumi.String("value11"),
						"key12": pulumi.String("value12"),
					},
				},
			},
			AutoMitigate: pulumi.Bool(true),
			Criteria: &monitor.MetricAlertMultipleResourceMultipleMetricCriteriaArgs{
				AllOf: pulumi.Array{
					monitor.MetricCriteria{
						CriterionType: "StaticThresholdCriterion",
						Dimensions: []monitor.MetricDimension{
							{
								Name:     "ActivityName",
								Operator: "Include",
								Values: []string{
									"*",
								},
							},
							{
								Name:     "StatusCode",
								Operator: "Include",
								Values: []string{
									"200",
								},
							},
						},
						MetricName:      "Availability",
						MetricNamespace: "Microsoft.KeyVault/vaults",
						Name:            "Metric1",
						Operator:        monitor.OperatorGreaterThan,
						Threshold:       55,
						TimeAggregation: monitor.AggregationTypeEnumAverage,
					},
				},
				OdataType: pulumi.String("Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria"),
			},
			Description:         pulumi.String("This is the description of the rule1"),
			Enabled:             pulumi.Bool(true),
			EvaluationFrequency: pulumi.String("PT1H"),
			Location:            pulumi.String("global"),
			ResourceGroupName:   pulumi.String("gigtest"),
			RuleName:            pulumi.String("MetricAlertOnMultipleDimensions"),
			Scopes: pulumi.StringArray{
				pulumi.String("/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.KeyVault/vaults/keyVaultResource"),
			},
			Severity:   pulumi.Int(3),
			Tags:       pulumi.StringMap{},
			WindowSize: pulumi.String("P1D"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var metricAlert = new AzureNative.Monitor.MetricAlert("metricAlert", new()
    {
        Actions = new[]
        {
            new AzureNative.Monitor.Inputs.MetricAlertActionArgs
            {
                ActionGroupId = "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2",
                WebHookProperties = 
                {
                    { "key11", "value11" },
                    { "key12", "value12" },
                },
            },
        },
        AutoMitigate = true,
        Criteria = new AzureNative.Monitor.Inputs.MetricAlertMultipleResourceMultipleMetricCriteriaArgs
        {
            AllOf = new[]
            {
                new AzureNative.Monitor.Inputs.MetricCriteriaArgs
                {
                    CriterionType = "StaticThresholdCriterion",
                    Dimensions = new[]
                    {
                        new AzureNative.Monitor.Inputs.MetricDimensionArgs
                        {
                            Name = "ActivityName",
                            Operator = "Include",
                            Values = new[]
                            {
                                "*",
                            },
                        },
                        new AzureNative.Monitor.Inputs.MetricDimensionArgs
                        {
                            Name = "StatusCode",
                            Operator = "Include",
                            Values = new[]
                            {
                                "200",
                            },
                        },
                    },
                    MetricName = "Availability",
                    MetricNamespace = "Microsoft.KeyVault/vaults",
                    Name = "Metric1",
                    Operator = AzureNative.Monitor.Operator.GreaterThan,
                    Threshold = 55,
                    TimeAggregation = AzureNative.Monitor.AggregationTypeEnum.Average,
                },
            },
            OdataType = "Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria",
        },
        Description = "This is the description of the rule1",
        Enabled = true,
        EvaluationFrequency = "PT1H",
        Location = "global",
        ResourceGroupName = "gigtest",
        RuleName = "MetricAlertOnMultipleDimensions",
        Scopes = new[]
        {
            "/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.KeyVault/vaults/keyVaultResource",
        },
        Severity = 3,
        Tags = null,
        WindowSize = "P1D",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.monitor.MetricAlert;
import com.pulumi.azurenative.monitor.MetricAlertArgs;
import com.pulumi.azurenative.monitor.inputs.MetricAlertActionArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var metricAlert = new MetricAlert("metricAlert", MetricAlertArgs.builder()
            .actions(MetricAlertActionArgs.builder()
                .actionGroupId("/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2")
                .webHookProperties(Map.ofEntries(
                    Map.entry("key11", "value11"),
                    Map.entry("key12", "value12")
                ))
                .build())
            .autoMitigate(true)
            .criteria(MetricAlertMultipleResourceMultipleMetricCriteriaArgs.builder()
                .allOf(MetricCriteriaArgs.builder()
                    .criterionType("StaticThresholdCriterion")
                    .dimensions(                    
                        MetricDimensionArgs.builder()
                            .name("ActivityName")
                            .operator("Include")
                            .values("*")
                            .build(),
                        MetricDimensionArgs.builder()
                            .name("StatusCode")
                            .operator("Include")
                            .values("200")
                            .build())
                    .metricName("Availability")
                    .metricNamespace("Microsoft.KeyVault/vaults")
                    .name("Metric1")
                    .operator("GreaterThan")
                    .threshold(55)
                    .timeAggregation("Average")
                    .build())
                .odataType("Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria")
                .build())
            .description("This is the description of the rule1")
            .enabled(true)
            .evaluationFrequency("PT1H")
            .location("global")
            .resourceGroupName("gigtest")
            .ruleName("MetricAlertOnMultipleDimensions")
            .scopes("/subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.KeyVault/vaults/keyVaultResource")
            .severity(3)
            .tags(Map.ofEntries(
            ))
            .windowSize("P1D")
            .build());

    }
}
resources:
  metricAlert:
    type: azure-native:monitor:MetricAlert
    properties:
      actions:
        - actionGroupId: /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/gigtest/providers/microsoft.insights/actiongroups/group2
          webHookProperties:
            key11: value11
            key12: value12
      autoMitigate: true
      criteria:
        allOf:
          - criterionType: StaticThresholdCriterion
            dimensions:
              - name: ActivityName
                operator: Include
                values:
                  - '*'
              - name: StatusCode
                operator: Include
                values:
                  - '200'
            metricName: Availability
            metricNamespace: Microsoft.KeyVault/vaults
            name: Metric1
            operator: GreaterThan
            threshold: 55
            timeAggregation: Average
        odataType: Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria
      description: This is the description of the rule1
      enabled: true
      evaluationFrequency: PT1H
      location: global
      resourceGroupName: gigtest
      ruleName: MetricAlertOnMultipleDimensions
      scopes:
        - /subscriptions/14ddf0c5-77c5-4b53-84f6-e1fa43ad68f7/resourceGroups/gigtest/providers/Microsoft.KeyVault/vaults/keyVaultResource
      severity: 3
      tags: {}
      windowSize: P1D

The dimensions array filters which metric data points trigger the alert. Each dimension has a name (like ActivityName or StatusCode), an operator (Include or Exclude), and values to match. Here, the alert monitors Key Vault availability but only for operations matching any activity name and HTTP 200 responses. This prevents alerts on expected failures or maintenance operations.

Monitor Application Insights availability tests

Application Insights web tests probe endpoints from multiple locations. Availability alerts fire when tests fail from enough locations.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const metricAlert = new azure_native.monitor.MetricAlert("metricAlert", {
    actions: [],
    criteria: {
        componentId: "/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example",
        failedLocationCount: 2,
        odataType: "Microsoft.Azure.Monitor.WebtestLocationAvailabilityCriteria",
        webTestId: "/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example",
    },
    description: "Automatically created alert rule for availability test \"component-example\" a",
    enabled: true,
    evaluationFrequency: "PT1M",
    location: "global",
    resourceGroupName: "rg-example",
    ruleName: "webtest-name-example",
    scopes: [
        "/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example",
        "/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example",
    ],
    severity: 4,
    tags: {
        "hidden-link:/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example": "Resource",
        "hidden-link:/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example": "Resource",
    },
    windowSize: "PT15M",
});
import pulumi
import pulumi_azure_native as azure_native

metric_alert = azure_native.monitor.MetricAlert("metricAlert",
    actions=[],
    criteria={
        "component_id": "/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example",
        "failed_location_count": 2,
        "odata_type": "Microsoft.Azure.Monitor.WebtestLocationAvailabilityCriteria",
        "web_test_id": "/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example",
    },
    description="Automatically created alert rule for availability test \"component-example\" a",
    enabled=True,
    evaluation_frequency="PT1M",
    location="global",
    resource_group_name="rg-example",
    rule_name="webtest-name-example",
    scopes=[
        "/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example",
        "/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example",
    ],
    severity=4,
    tags={
        "hidden-link:/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example": "Resource",
        "hidden-link:/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example": "Resource",
    },
    window_size="PT15M")
package main

import (
	monitor "github.com/pulumi/pulumi-azure-native-sdk/monitor/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := monitor.NewMetricAlert(ctx, "metricAlert", &monitor.MetricAlertArgs{
			Actions: monitor.MetricAlertActionArray{},
			Criteria: &monitor.WebtestLocationAvailabilityCriteriaArgs{
				ComponentId:         pulumi.String("/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example"),
				FailedLocationCount: pulumi.Float64(2),
				OdataType:           pulumi.String("Microsoft.Azure.Monitor.WebtestLocationAvailabilityCriteria"),
				WebTestId:           pulumi.String("/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example"),
			},
			Description:         pulumi.String("Automatically created alert rule for availability test \"component-example\" a"),
			Enabled:             pulumi.Bool(true),
			EvaluationFrequency: pulumi.String("PT1M"),
			Location:            pulumi.String("global"),
			ResourceGroupName:   pulumi.String("rg-example"),
			RuleName:            pulumi.String("webtest-name-example"),
			Scopes: pulumi.StringArray{
				pulumi.String("/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example"),
				pulumi.String("/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example"),
			},
			Severity: pulumi.Int(4),
			Tags: pulumi.StringMap{
				"hidden-link:/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example": pulumi.String("Resource"),
				"hidden-link:/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example":      pulumi.String("Resource"),
			},
			WindowSize: pulumi.String("PT15M"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var metricAlert = new AzureNative.Monitor.MetricAlert("metricAlert", new()
    {
        Actions = new[] {},
        Criteria = new AzureNative.Monitor.Inputs.WebtestLocationAvailabilityCriteriaArgs
        {
            ComponentId = "/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example",
            FailedLocationCount = 2,
            OdataType = "Microsoft.Azure.Monitor.WebtestLocationAvailabilityCriteria",
            WebTestId = "/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example",
        },
        Description = "Automatically created alert rule for availability test \"component-example\" a",
        Enabled = true,
        EvaluationFrequency = "PT1M",
        Location = "global",
        ResourceGroupName = "rg-example",
        RuleName = "webtest-name-example",
        Scopes = new[]
        {
            "/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example",
            "/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example",
        },
        Severity = 4,
        Tags = 
        {
            { "hidden-link:/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example", "Resource" },
            { "hidden-link:/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example", "Resource" },
        },
        WindowSize = "PT15M",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.monitor.MetricAlert;
import com.pulumi.azurenative.monitor.MetricAlertArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var metricAlert = new MetricAlert("metricAlert", MetricAlertArgs.builder()
            .actions()
            .criteria(WebtestLocationAvailabilityCriteriaArgs.builder()
                .componentId("/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example")
                .failedLocationCount(2.0)
                .odataType("Microsoft.Azure.Monitor.WebtestLocationAvailabilityCriteria")
                .webTestId("/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example")
                .build())
            .description("Automatically created alert rule for availability test \"component-example\" a")
            .enabled(true)
            .evaluationFrequency("PT1M")
            .location("global")
            .resourceGroupName("rg-example")
            .ruleName("webtest-name-example")
            .scopes(            
                "/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example",
                "/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example")
            .severity(4)
            .tags(Map.ofEntries(
                Map.entry("hidden-link:/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example", "Resource"),
                Map.entry("hidden-link:/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example", "Resource")
            ))
            .windowSize("PT15M")
            .build());

    }
}
resources:
  metricAlert:
    type: azure-native:monitor:MetricAlert
    properties:
      actions: []
      criteria:
        componentId: /subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example
        failedLocationCount: 2
        odataType: Microsoft.Azure.Monitor.WebtestLocationAvailabilityCriteria
        webTestId: /subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example
      description: Automatically created alert rule for availability test "component-example" a
      enabled: true
      evaluationFrequency: PT1M
      location: global
      resourceGroupName: rg-example
      ruleName: webtest-name-example
      scopes:
        - /subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example
        - /subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example
      severity: 4
      tags:
        ? hidden-link:/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/components/webtest-name-example
        : Resource
        ? hidden-link:/subscriptions/12345678-1234-1234-1234-123456789101/resourcegroups/rg-example/providers/microsoft.insights/webtests/component-example
        : Resource
      windowSize: PT15M

The WebtestLocationAvailabilityCriteria type is specific to Application Insights availability monitoring. The failedLocationCount property sets how many test locations must fail before alerting; here, 2 or more failures trigger the alert. The componentId references the Application Insights resource, while webTestId points to the availability test. The special hidden-link tags in the tags property connect the alert to both resources, enabling proper visualization in the Azure portal.

Beyond these examples

These snippets focus on specific metric alert features: static and dynamic threshold evaluation, multi-resource and dimension-based filtering, and Application Insights availability monitoring. They’re intentionally minimal rather than full monitoring solutions.

The examples may reference pre-existing infrastructure such as virtual machines, Key Vaults, Application Insights components, action groups for notifications, and web tests for availability monitoring. They focus on configuring the alert rule rather than provisioning the monitored resources.

To keep things focused, common alert patterns are omitted, including:

  • Auto-mitigation behavior (autoMitigate)
  • Historical data filtering (ignoreDataBefore)
  • Subscription and resource group scoping patterns
  • Multiple criteria combinations (allOf with multiple conditions)

These omissions are intentional: the goal is to illustrate how each alert feature is wired, not provide drop-in monitoring modules. See the MetricAlert resource reference for all available configuration options.

Let's create Azure Metric Alerts

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Alert Criteria & Thresholds
What's the difference between dynamic and static threshold criteria?
Dynamic thresholds (DynamicThresholdCriterion) use machine learning to adapt based on historical metric patterns, while static thresholds (StaticThresholdCriterion) use fixed values you specify. Dynamic thresholds require configuring alertSensitivity and failingPeriods instead of a fixed threshold.
How do failing periods work for dynamic threshold alerts?
Configure minFailingPeriodsToAlert and numberOfEvaluationPeriods within failingPeriods. For example, setting both to 4 means the alert triggers when 4 out of the last 4 evaluation periods exceed the dynamic threshold.
How do I filter metrics by specific dimensions?
Add dimension filters to your criteria using the dimensions array. Each dimension needs a name, operator (Include or Exclude), and values array. Use "*" as a value to include all dimension values.
Scope & Resource Targeting
Can I monitor multiple resources with a single alert?
Yes, specify multiple resource IDs in the scopes array and use Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria as the odataType. You must also set targetResourceType and targetResourceRegion.
When do I need to specify targetResourceType and targetResourceRegion?
These properties are required when your scopes contains a subscription, resource group, or more than one resource. They’re not needed for single-resource alerts.
Can I change the scope of an alert after creation?
You cannot change the scope of metric alerts based on logs after creation. For other alert types, you’ll need to verify whether scope changes are supported.
Timing & Evaluation
What format do I use for evaluationFrequency and windowSize?
Use ISO 8601 duration format. Common values include PT1M (1 minute), PT5M (5 minutes), PT1H (1 hour), PT15M (15 minutes), and P1D (1 day). The PT prefix indicates time duration, while P alone indicates period.
What's the difference between evaluationFrequency and windowSize?
evaluationFrequency controls how often the alert checks metrics (e.g., every 1 minute), while windowSize defines the time period of data analyzed during each check (e.g., last 15 minutes).
Configuration & Behavior
What do the severity levels mean?
Severity ranges from 0 to 4, where 0 is the most critical and 4 is the least critical. Choose the severity based on the alert’s importance to your operations.
What does autoMitigate do?
When autoMitigate is true (the default), Azure automatically resolves the alert when the condition is no longer met. Set it to false if you want to manually resolve alerts.
How do I ignore old data when using dynamic thresholds?
Set ignoreDataBefore to a timestamp in ISO 8601 format. The dynamic threshold will only use metric data after this date when calculating baselines.
How do I create alerts for Application Insights availability tests?
Use WebtestLocationAvailabilityCriteria as your criteria type, specifying componentId, webTestId, and failedLocationCount. Link both the web test and component in your scopes.

Using a different cloud?

Explore monitoring guides for other cloud providers: