Skip to Main Content

Working with Azure Monitor Rest API

We're delighted to welcome back Martin Ehrnst, for another special guest blog.

Martin works at Intility, one of Norway's leading Managed Service Providers, managing a SCOM deployment covering well over 3000 on-prem servers. With the recent deprecation of the Operations Management Suite (OMS), Martin and Intility have moved to Azure Monitor for their Azure monitoring. As part of their Azure story, Martin has written an excellent blog on Azure Monitor and it's REST API. Read on to find out more.

Working with Azure Monitor Rest API

Martin Erhnst

Before delving into Azure monitor Rest API and PowerShell, let’s take a little step back. Azure monitor released in public preview a little over a year ago (September 2016). Introduced as “The built-in solution to make monitoring available for all Azure users”.
At that time I was personally all over the Operations Management Suite or OMS which is now a deprecated brand. All features from OMS is now available under “Monitoring + Management” in the Azure Marketplace.

Therefore, Azure Monitor went a bit under my radar, but when OMS shifted we started to see more and more about Azure Monitor being the one stop shop for Azure monitoring. Especially the alerting feature seems to be richer in Monitor than in Log Analytics and it is my (and others) anticipation that we will see Monitor as the default alert tool, for both metrics and activity logs.

So as part of my never-ending story, Monitoring Azure as a CSP provider. Let’s take a look at Azure Monitor and it’s REST API

We want to retrieve alert rules and incidents (alerts) programmatically, but first we create an alert rule to work with through the GUI. In th Azure portal:

At this time of writing the alert rule is bound to a specific resource. I hope we will see the ability to create rules based on resource type. ie: you want all web apps to have the same standard alert rules for response time.

Locate Azure monitor

Find your resource and metric (or you can jump straight in to alerts)

Verify that your alert rule exists

Retrieve Azure Monitor alerts and incidents

From Powershell I am connecting to AAD and generating authentication header, reusing code from earlier blog post about Azure Resource health. For the purpose of this post I will focus on these two Azure Monitor API endpoints: Alert Rules – List By Resource Group and Alert Rule Incidents – List By Alert Rule.

After you have authenticated against Azure AD, and if using my previous sample you should have the following header available.

$result = Get-AADAppoAuthToken -ClientID $AzureApplicationID -ClientSecret $ClientSecret -TenantId $TenantId
$AuthKey = "Bearer " + ($result.access_token)
$authHeader = @{
    'Content-Type'  = 'application/json'
    'Accept'        = 'application/json'
    'Authorization' = $AuthKey
}

Using this header we call the alert rules endpoint to get our alert rules. Pay attention to the URL, as it requires you to specify a subscription id and the resource group name.

$alertRules = Invoke-RestMethod -Method GET "https://management.azure.com/subscriptions/$SubscriptionId/resourcegroups/$ResourceGroupName/providers/microsoft.insights/alertrules?api-version=2016-03-01" -Headers $authHeader

The output from the above should look something like this. I only have one alert configured for the resource group

id : /subscriptions/a2782f8e/resourceGroups/2017/providers/microsoft.insights/alertrules/name
name : name
type : Microsoft.Insights/alertRules
location : westeurope
tags : @{$type=Microsoft.WindowsAzure.Management.Common.Storage.CasePreservedDictionary,}
properties : @{name=No runs; description=; isEnabled=True; condition=; action=; lastUpdatedTime=2017-11-02T12:52:26.9091865Z; provisioningState=Succeeded; actions=System.Object[]}

Next we use the ID from our previus result as part of the URL to get our alert incidents

$Alert = $alertrules.id
(Invoke-RestMethod -Method GET "https://management.azure.com/$alert/incidents?api-version=$apiversion" -Headers $authHeader).value

I am jumping straight in to the ‘value’ node at this point. If youre alert rule have triggered an incident it will return a result. We see the time it was activated (and resolved if it’s old), a boolean value of its status, and some information on the resource itself.

id : L3N1YnNjcmlwdGlvbnMvZTUxNGRhY2EtYTA3Ny00NGYwLTljZmEtNjBlMzRjOTk1Zjk3L3Jlc291cmNlR3JvdXBzL1NlbWluYXIyMDE3L3Byb3ZpZGVycy9taWNyb3NvZnQuaW5zaWdodHMvYWxlcnRydWxlcy9ObyUyMHJ1bnMwNjM2NDUyMjM3NjcyODMwODI2
ruleName : /subscriptions/a2782f8e/resourceGroups/2017/providers/microsoft.insights/alertrules/name
isActive : True
activatedTime : 2017-11-02T12:49:27.2830826+00:00
resolvedTime :
targetResourceId :
targetResourceLocation :
legacyResourceId :

Below I have tied everything together, using my Azure App authentication function we generate the auth header and retrieves alert rules based on user input.

param (
    # Your azure ad application ID
    [Parameter(Mandatory)]
    [String]
    $AzureApplicationID,

    # Azure AD application secret
    [Parameter(Mandatory)]
    [String]
    $ClientSecret,

    # Azure tenant id. IE: test.no or test.onmicrosoft.com
    [Parameter(Mandatory)]
    [String]
    $TenantId,

    # Azure subscription ID
    [Parameter(Mandatory)]
    [String]
    $SubscriptionId,

    # Azure Resource group name
    [Parameter(Mandatory)]
    [String]
    $ResourceGroupName

)

$ApiVersion = "2016-03-01"

#region functions

function Get-AADAppoAuthToken {
    <#
    .SYNOPSIS
       Function to connect to the Microsoft login OAuth endpoint and return an OAuth token.
    .DESCRIPTION
        Generate Azure AD oauth token.
       You can specify the resource you want in the paramenter. Default is management.core.windows.net
       Parts of this function is created from these examples: https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-rest-api-walkthrough

    .PARAMETER ClientID
        Azure AD application ID

    .PARAMETER ClientSecret
        Your application secret.

    .PARAMETER TenantId
        Your tenant domain name. test.onmicrosoft.com

    .PARAMETER ResourceName
        Specify if you are accessing other resources than https://management.core.windows.net
        For example microsoft partner center would have https://api.partnercenter.microsoft.com

    .EXAMPLE
        Get-AADAppoAuthToken -ClientID 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' -ClientSecret <application secret> -TenantId "test.no" will return
        token_type     : Bearer
        expires_in     : 3600
        ext_expires_in : 0
        expires_on     : 1505133623
        not_before     : 1505129723
        resource       : https://management.core.windows.net/
        access_token   : eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IkhIQnlLVS0wRHFBcU1aaDZaRlBkMlZXYU90ZyIsImtpZCI6IkhIQnlLVS0wRHFBcU1aaDZaRlB
                         kMlZXYU90ZyJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuY29yZS53aW5kb3dzLm5ldC8iLCJpc3MiOiJodHRwczovL3N0cy
                 
    .NOTES
        v1.0
        Martin Ehrnst 2017
    #>
    [Cmdletbinding()]
    Param(
        [Parameter(Mandatory = $true)]
        [string]$ClientID,
        [Parameter(Mandatory = $true)]
        [string]$ClientSecret,
        [Parameter(Mandatory = $true)]
        [string]$TenantId,
        [Parameter(Mandatory = $false)]
        [string]$ResourceName = "https://management.core.windows.net/"
    )

    $LoginURL = 'https://login.windows.net'

    #Get application access token
    $Body = @{
        grant_type    = "client_credentials";
        resource      = $ResourceName;
        client_id     = $ClientID;
        client_secret = $ClientSecret
    }

    Return Invoke-RestMethod -Method Post -Uri $LoginURL/$TenantId/oauth2/token -Body $Body
}

#endregion


$result = Get-AADAppoAuthToken -ClientID $AzureApplicationID -ClientSecret $ClientSecret -TenantId $TenantId
$AuthKey = "Bearer " + ($result.access_token)
$authHeader = @{
    'Content-Type'  = 'application/json'
    'Accept'        = 'application/json'
    'Authorization' = $AuthKey
}

#Get all resource group alert rules
$AlertRules = (Invoke-RestMethod -Method GET "https://management.azure.com/subscriptions/$SubscriptionId/resourcegroups/$ResourceGroupName/providers/microsoft.insights/alertrules?api-version=$apiversion" -Headers $authHeader).value

Wrapping up

We now know the basic concepts on how we authenticate and retrieve alert rules and incidents from Azure Monitor through it’s rest API using Powershell. From here we can easily expand our work to create new alert rules or retrieve metrics from our resources which lets us build custom solutions on prem or any where else.

Hopefully, I can soon provide some insights on how we are building our CSP monitoring solution in a single blog post, using the different tools mentioned in my latest posts.

About Martin Ehrnst

Martin works as a Systems Engineer for Intility, one of Norway's leading enterprise cloud providers and has extensive experience with System Center, Azure and Windows server products.

I've you've enjoyed this article we highly recommend bookmarking Martin's own blog and you can also follow him via Twitter and LinkedIn.