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 Configuration & Scope
Can I change the scope of a metric alert after creation?
You cannot change the scope of metric rules based on logs. For other metric alerts, you can modify the scopes property, but log-based rules require recreation to change scope.
How do I monitor multiple resources with a single alert?
Specify multiple resource IDs in the scopes array. When monitoring multiple resources, you must also set targetResourceType and targetResourceRegion.
When are targetResourceType and targetResourceRegion required?
These properties are mandatory when your scope contains a subscription, resource group, or more than one resource.
Can I create alerts at the subscription or resource group level?
Yes, you can scope alerts to entire subscriptions or resource groups by including their resource IDs in the scopes array. You must specify targetResourceType and targetResourceRegion for these scenarios.
Alert Criteria & Thresholds
What's the difference between dynamic and static threshold alerts?
Static thresholds use fixed values (StaticThresholdCriterion), while dynamic thresholds adapt based on historical patterns (DynamicThresholdCriterion). Dynamic thresholds require configuring alertSensitivity and failingPeriods.
How do I configure dynamic threshold sensitivity?
Set alertSensitivity to Low, Medium, or High, and configure failingPeriods with minFailingPeriodsToAlert and numberOfEvaluationPeriods to control when alerts trigger.
How do I filter alerts using metric dimensions?
Add a dimensions array to your criteria with name, operator (Include/Exclude), and values. Use “*” to include all dimension values.
How do I ignore historical data for dynamic thresholds?
Set ignoreDataBefore to an ISO 8601 timestamp. The dynamic threshold will only use data after this date for baseline calculations.
Timing & Evaluation
What format do evaluationFrequency and windowSize use?
Both use ISO 8601 duration format. Examples: PT1M (1 minute), PT15M (15 minutes), PT1H (1 hour), P1D (1 day).
What do the severity levels mean?
Severity ranges from 0 (critical) to 4 (informational). Set the severity property to an integer between 0 and 4.
Actions & Auto-Resolution
Do alerts automatically resolve when conditions clear?
Yes, by default. The autoMitigate property defaults to true, automatically resolving alerts when conditions are no longer met. Set it to false to require manual resolution.
How do I configure alert actions?
Add action groups to the actions array with actionGroupId and optional webHookProperties for custom webhook data.

Using a different cloud?

Explore monitoring guides for other cloud providers: