Azure Device Groups

Last updated on 25 February, 2021

Overview

You can use LogicMonitor’s REST API to manage Azure groups. Azure groups are device groups with a few key differences. This document covers the differences, as well as how to add and update Azure groups.

URI: /device/groups

Azure Group Differentiators

Azure Specific groupType

Azure groups have a special groupType value. Specifically, normal and dynamic groups will have a groupType value of Normal, while Azure device groups will have a value of Azure/SERVICE, where SERVICE is the Azure service the group was created for (for example, VirtualMachine, SQLDatabase, AppService, and so on). The Azure account level group will have a groupType value of Azure/AzureRoot.

Azure Specific Fields

The azureRegionsInfo, azureTestResult and azureTestResultCode are all read-only fields specific to Azure groups. More importantly, Azure group specific information such as Azure account credentials and Azure service/region configurations are included in the “extra” object in the device group JSON.

Specifically, the extra object includes the following information:

Property Description Type Example
default The default service settings configured for the Azure group. This should include selectAll (can be used to select all regions for monitoring), monitoringRegions (can be used to select specific regions for monitoring), deadOperation (MANUALLY | KEEP_7_DAYS | KEEP_14_DAYS | KEEP_30_DAYS | IMMEDIATELY), useDefault (not applicable to default object), nameFilter (not applicable to default object), tags (used to specify tag filters) JSON Array “default”: { “disableTerminatedHostAlerting”: true,”normalCollectorConfig”: null,”customNSPSchedule”: “”,”selectAll”: true,”monitoringRegions”: [“EAST_ASIA”, “SOUTHEAST_ASIA”, “CENTRAL_US”, “EAST_US”, “EAST_US_2”, “WEST_US”, “NORTH_CENTRAL_US”, “SOUTH_CENTRAL_US”, “WEST_CENTRAL_US”, “WEST_US_2”, “NORTH_EUROPE”, “WEST_EUROPE”, “JAPAN_WEST”, “JAPAN_EAST”, “BRAZIL_SOUTH”, “AUSTRALIA_EAST”, “AUSTRALIA_SOUTHEAST”, “SOUTH_INDIA”, “CENTRAL_INDIA”, “WEST_INDIA”, “CANADA_CENTRAL”, “CANADA_EAST”, “UK_SOUTH”, “UK_WEST”, “FRANCE_CENTRAL”, “SOUTH_AFRICA_NORTH”, “SOUTH_AFRICA_WEST”, “KOREA_CENTRAL”, “KOREA_SOUTH”, “AUSTRALIA_CENTRAL”, “AUSTRALIA_CENTRAL_2”, “FRANCE_SOUTH”, “GERMANY_CENTRAL”, “GERMANY_NORTH”, “GERMANY_NORTH_EAST”, “SWITZERLAND_NORTH”, “SWITZERLAND_WEST”], “deviceDisplayNameTemplate”: “”, “disableStopTerminateHostMonitor”: true, “deadOperation”: “KEEP_7_DAYS”, “useDefault”: true, “nameFilter”: [], “tags”: []}
services The service settings for the Azure Group. This should include selectAll (can be used to select all regions for monitoring), monitoringRegions (can be used to select specific regions for monitoring), deadOperation (MANUALLY | KEEP_7_DAYS | KEEP_14_DAYS | KEEP_30_DAYS | IMMEDIATELY), useDefault (whether or not default settings should be applied), nameFilter, tags (used to specify tag filters) JSON Array “VIRTUALMACHINE”: { “disableTerminatedHostAlerting”: true, “normalCollectorConfig”: { “collectors”: [], “enable”: false }, “customNSPSchedule”: “”, “selectAll”: true, “monitoringRegions”: [“EAST_ASIA”, “SOUTHEAST_ASIA”, “CENTRAL_US”, “EAST_US”, “EAST_US_2”, “WEST_US”, “NORTH_CENTRAL_US”, “SOUTH_CENTRAL_US”, “WEST_CENTRAL_US”, “WEST_US_2”, “NORTH_EUROPE”, “WEST_EUROPE”, “JAPAN_WEST”, “JAPAN_EAST”, “BRAZIL_SOUTH”, “AUSTRALIA_EAST”, “AUSTRALIA_SOUTHEAST”, “SOUTH_INDIA”, “CENTRAL_INDIA”, “WEST_INDIA”, “CANADA_CENTRAL”, “CANADA_EAST”, “UK_SOUTH”, “UK_WEST”, “FRANCE_CENTRAL”, “SOUTH_AFRICA_NORTH”, “SOUTH_AFRICA_WEST”, “KOREA_CENTRAL”, “KOREA_SOUTH”, “AUSTRALIA_CENTRAL”, “AUSTRALIA_CENTRAL_2”, “FRANCE_SOUTH”, “GERMANY_CENTRAL”, “GERMANY_NORTH”, “GERMANY_NORTH_EAST”, “SWITZERLAND_NORTH”, “SWITZERLAND_WEST” ], “deviceDisplayNameTemplate”: “”, “disableStopTerminateHostMonitor”: true, “deadOperation”: “KEEP_7_DAYS”, “useDefault”: true, “nameFilter”: [], “tags”: [] }
account The account level information for the Azure Group. JSON Array “account”: { “schedule”: “0 * * * *”, “country”: “USA”, “billingInfo”: [], “clientId”: “1912c6eb-e51f-40a0-a4c7-a939ded64cae”, “secretKey”: “********”, “collectorDescription”: “Cloud Collector”, “subscriptionIds”: “d499ee70-fb15-454a-9c72-dcfa08078448”, “tenantId”: “dc818e23-4f5a-4b7e-bdfa-66de5eb19691”, “collectorId”: -2 }

Adding an Azure Group

LogicMonitor requires a Monitoring Reader Azure AD role to authenticate Azure Monitor API requests. When you add your Azure account into LogicMonitor, you’ll need to provide such a role. As such, to add an Azure Group you’ll need to:

  • Make a POST request to the /device/groups resource to add your Azure account into LogicMonitor.

Example: Post New Azure Group

The following Python script request adds an Azure Group named “LM Azure” with the following parameters:

  • The default service settings section only has four regions selected: central-us, east-us, east-us-2, and west-us and resources are not set to be automatically deleted.
  • The VIRTUALMACHINE service is selected for monitoring, where VIRTUALMACHINE has one tag filter applied, three regions selected, and resources are set to be automatically deleted after seven days.
  • The Auto Discovery frequency for the account is not set, and will default to every hour.
  • Additionally, a property named ‘customer’ is added to the group and set to the value ‘customerA’.
#!/bin/env python

import requests
import json
import hashlib
import base64
import time
import hmac

#Account Info
AccessId ='48v2wRzfK94y53sq5EuF'
AccessKey ='H_D9i(f5~B^U36^K6i42=^nS~e75gy382Bf6{)P+'
Company = 'api'

#Request Info
httpVerb ='POST'
resourcePath = '/device/groups'
queryParams =''
data = '{"parentId" : 1, "name" : "LM Azure", "description" : "This is a test description for an Azure account.", "groupType" : "Azure/AzureRoot", "disableAlerting" : false, "customProperties" : [{"name": "customer", "value":"customerA"}], "extra":{"account": {"schedule": "0 * * * *", "country": "USA", "billingInfo": [], "clientId": "1912c6eb-e51f-40a0-a4c7-a939ded64cae", "secretKey": "********", "collectorDescription": "Cloud Collector", "subscriptionIds": "d499ee70-fb15-454a-9c72-dcfa08078448", "tenantId": "dc818e23-4f5a-4b7e-bdfa-66de5eb19691", "collectorId": -2}, "default": {"disableTerminatedHostAlerting": true, "normalCollectorConfig": null, "customNSPSchedule": "", "selectAll": true, "monitoringRegions": ["CENTRAL_US", "EAST_US", "EAST_US_2", "WEST_US" ], "deviceDisplayNameTemplate": "", "disableStopTerminateHostMonitor": true, "deadOperation": "KEEP_7_DAYS", "useDefault": true, "nameFilter": [], "tags": []}, "services": {"VIRTUALMACHINE": {"disableTerminatedHostAlerting": true, "normalCollectorConfig": {"collectors": [], "enable": false}, "customNSPSchedule": "", "selectAll": true, "monitoringRegions": ["CENTRAL_US", "EAST_US_2", "WEST_US" ], "deviceDisplayNameTemplate": "", "disableStopTerminateHostMonitor": true, "deadOperation": "KEEP_7_DAYS", "useDefault": true, "nameFilter": [], "tags": [{"foo": "bar"}]}}}}'

#Construct URL 
url = 'https://'+ Company +'.logicmonitor.com/santaba/rest' + resourcePath + queryParams

#Get current time in milliseconds
epoch = str(int(time.time() * 1000))

#Concatenate Request details
requestVars = httpVerb + epoch + data + resourcePath

# Construct signature
hmac1 =  hmac.new(AccessKey.encode(),msg=requestVars.encode(),digestmod=hashlib.sha256).hexdigest()
signature = base64.b64encode(hmac1.encode())

# Construct headers
auth = 'LMv1 ' + AccessId + ':' + signature.decode() + ':' + epoch
headers = {'Content-Type':'application/json','Authorization':auth}

#Make request
response = requests.post(url, data=data, headers=headers)

# Print status and body of response
print('Response Status:',response.status_code)
print('Response Body:',response.content) 
Python 3

Updating an Azure Group

If you’re updating an Azure Group, we recommend first making a GET request to get the group JSON, parsing the output, replacing the desired values, and then using PUT to update the resource.

Example: Update Azure Group

The following Python script makes a GET request to get device group 39 (which happens to be the Azure root group), parses out the response, replaces the assigned Collector, adds the configuration object, and then makes a PUT request to update the group 39.

#!/bin/env python

import requests
import json
import hashlib
import base64
import time
import hmac

#Account Info
AccessId ='48v2wRzfK94y53sq5EuF'
AccessKey ='H_D9i(f5~B^U36^K6i42=^nS~e75gy382Bf6{)P+'
Company = 'api'

#Request Info
httpVerb ='GET'
resourcePath = '/device/groups/39'

#Construct URL 
url = 'https://'+ Company +'.logicmonitor.com/santaba/rest' + resourcePath 

#Get current time in milliseconds
epoch = str(int(time.time() * 1000))

#Concatenate Request details
requestVars = httpVerb + epoch + resourcePath

# Construct signature
hmac1 =  hmac.new(AccessKey.encode(),msg=requestVars.encode(),digestmod=hashlib.sha256).hexdigest()
signature = base64.b64encode(hmac1.encode())

# Construct headers
auth = 'LMv1 ' + AccessId + ':' + signature.decode() + ':' + epoch
headers = {'Content-Type':'application/json','Authorization':auth}

#Make request
response = requests.get(url, headers=headers)

#Parse response
jsonResponse = json.loads(response.content)

#Change Collector Id and add configuration object
group = jsonResponse['data']
group['extra']['account']['collectorId'] = 218

#PUT Request Info
httpVerb ='PUT'
resourcePath = '/device/groups/39'
queryParams =''
data = str(json.dumps(group))

#Construct URL 
url = 'https://'+ Company +'.logicmonitor.com/santaba/rest' + resourcePath +queryParams

#Get current time in milliseconds
epoch = str(int(time.time() * 1000))

#Concatenate Request details
requestVars = httpVerb + epoch + data + resourcePath

# Construct signature
hmac1 =  hmac.new(AccessKey.encode(),msg=requestVars.encode(),digestmod=hashlib.sha256).hexdigest()
signature = base64.b64encode(hmac1.encode())

# Construct headers
auth = 'LMv1 ' + AccessId + ':' + signature.decode() + ':' + epoch
headers = {'Content-Type':'application/json','Authorization':auth}

#Make request
putResponse = requests.put(url, data=data, headers=headers)

# Print status and body of response
print('Response Status:',response.status_code)
print('Response Body:',response.content
Python 3
In This Article