How to create an alert rule using PowerShell and Azure CLI

How to create an alert rule using PowerShell and Azure CLI

Introduction

I found it rather difficult to create an alert rule using PowerShell as opposed to using Azure CLI. That's why I thought it is worth a post.

In the following tiny howto, we are going to create an alert that gets triggered when the average CPU load of a virtual machine stays above 90% for a duration of 5 minutes. I assume there exists a resource group called rg-training and a virtual machine named VM1.

In general, an alert rule consists of the following components.

Component Description
Scope The resource(s) you want to monitor
Condition Configures when the alert rule should trigger the action
Action Group A list of actions to invoke when the alert rule triggers (optional)
Alert Rule Details Some identification information

Azure CLI

First, we need to create an action group that we later are going to use with the alert rule. This rule will send an email to defined recipients upon the rule triggers.

# Create an action group
az monitor action-group create \
    --name notify-admins \
    --resource-group rg-training \
    --action email my-action-name [email protected]
Have a look at az monitor action-group create -h for further actions that are available. For example you can also send out an SMS, trigger a webhook and so on.

Then we need to retrieve the ID of the virtual machine and store it for later use...

# Retrieve VM identifier used for scope parameter
$scope = az vm show \
    --name vm1 \
    --output tsv \
    --query id

Finally, we create a metric alert, that will trigger when the average CPU load stays above 90% for a duration of 5 minutes (measured once per minute).

# Create the actual alert
az monitor metrics alert create \
    --name alert2 \
    --resource-group rg-training \
    --scopes $scope \
    --condition "avg Percentage CPU > 90" \
    --window-size 5m \
    --evaluation-frequency 1m \
    --action notify-admins \
    --description "High CPU"

That was easy. Now let's have a look at the PowerShell variant, where things are a bit more complicated and long-winded.

Azure PowerShell

First, we need to create an action group receiver object and an action group.

# Creates an new action group receiver object in memory
$receiver = New-AzActionGroupReceiver `
    -Name "Admin" `
    -EmailAddress "[email protected]"

# Creates a new or updates an existing action group.
$actionGroup = Set-AzActionGroup `
    -Name "notify-admins" `
    -ShortName "ActionGroup1" `
    -ResourceGroupName "rg-training" `
    -Receiver $receiver
Have a look at the official documentation for further receivers that can be configured.

Now let's read back the action group and store it in a variable.

# Creates an ActionGroup reference object in memory.
$actionGroupId = New-AzActionGroup -ActionGroupId $actionGroup.Id
$actionGroupId will hold an object of type ActivityLogAlertActionGroup that is later required for the Add-AzMetricAlertRuleV2 cmdlet.

Okay great! now we need a condition.

# Creates a local criteria object that can be used to create a new metric alert
$condition = New-AzMetricAlertRuleV2Criteria `
    -MetricName "Percentage CPU" `
    -TimeAggregation Average `
    -Operator GreaterThan `
    -Threshold 0.1

And finally, we can put all the pieces together and call Add-AzMetricAlertRuleV2 as follows.

$windowSize = New-TimeSpan -Minutes 1
$frequency = New-TimeSpan -Minutes 1 
$targetResourceId = (Get-AzResource -Name VM1).ResourceId

# Adds or updates a V2 (non-classic) metric-based alert rule.
Add-AzMetricAlertRuleV2 `
    -Name "metricRule" `
    -ResourceGroupName "rg-training" `
    -WindowSize $windowSize `
    -Frequency $frequency `
    -TargetResourceId $targetResourceId `
    -Condition $condition `
    -ActionGroup $actionGroupId `
    -Severity 3

If Add-AzMetricAlertRuleV2 throws an exception at you like the one below, then make sure you are using the correct metric name.

Add-AzMetricAlertRuleV2: Exception type: ErrorResponseException, Message: Couldn't find a metric named <some_metric_you_entered>. Make sure the name is correct. Activity ID: <some-guid>., Code: BadRequest, Status code:BadRequest, Reason phrase: BadRequest

You can look up the correct metric names by issuing the cmdlet below. Make sure you replace the metric namespace with the resource type and ID of your choice.

# Gets metric definitions
$validMetrics = Get-AzMetricDefinition `
    -MetricNamespace "Microsoft.Compute/virtualMachine" `
    -ResourceId $targetResourceId)

# Get the values
$validMetrics.Name

Or alternatively, look them up in the documentation 😉That's it for today. I hope you enjoyed this post. Happy hacking! 😎

Further reading

New-AzActionGroupReceiver (Az.Monitor)
The New-AzActionGroupReceiver cmdlet creates new action group receiver in memory.
Set-AzActionGroup (Az.Monitor)
The Set-AzActionGroup cmdlet creates a new or updates an existing action group
Get-AzActionGroup (Az.Monitor)
The Get-AzActionGroup cmdlet gets one or more action groups.
New-AzActionGroup (Az.Monitor)
The New-AzActionGroup cmdlet creates an action group reference object in memory.
New-AzMetricAlertRuleV2Criteria (Az.Monitor)
The New-AzMetricAlertRuleV2Criteria cmdlet creates a local metric criteria object to be used as an input Add-AzMetricAlertRuleV2 cmdlet which creates a new metric alert rule.
Add-AzMetricAlertRuleV2 (Az.Monitor)
Adds or updates a V2 (non-classic) metric-based alert rule. The added rule is associated with a resource group and has a name. This cmdlet implements the ShouldProcess pattern, i.e. it might request confirmation from the user before actually creating, modifying, or removing the resource.