This article is about Implementing of CPU Quota Usage Alert for Azure Subscription. As part of my recent assignment, I successfully created a CPU quota usage alert for an Azure subscription using Azure Resource Manager (ARM) templates. The deployment enables real-time monitoring of CPU quota usage, providing proactive alerts to prevent potential resource exhaustion.
Upon deployment, the alert rules are accessible within the Azure Subscription portal, under Usage + Quotas > Total Regional vCPUs > Location. This view lists all alert rules associated with specific quota names and locations. Please note that any modifications to quota names or locations for an alert rule may affect its visibility in this list.
By fulfilling these requirements and leveraging ARM templates, the CPU quota usage alert system provides enhanced visibility and control over resource utilization, enabling prompt action to prevent quota breaches.
While creating this setup there are few prerequisite which I mentioned below.
Before creating alert I have already have created common Resource Group and User Assigned Identity as a prerequisite. These resources will be used while creating Quota usage alerts and action groups resources. Below is the PowerShell script you can use to deploy with ARM templates.
Download this code CPU_Quota_Alert_Azure_ARM_templates.zip here or it is also available on github.com.
New-AzResourceGroupDeployment -ResourceGroupName 'vcloud-lab.com' ` -TemplateFile "$PSScriptRoot\CPU_Quota_Alert_combined_template.json" ` -TemplateParameterFile "$PSScriptRoot\CPU_Quota_Alert_template_parameters.json" ` -Verbose ######################################################################################################### <# #Another way 2: Deploy Using a Parameters File # Variables # $resourceGroupName = "vcloud-lab.com" # $deploymentName = "QuotaAlertDeployment" # $templateFilePath = "D:\Projects\PowerShell\\subscription_quota_rule\action_group_template.json" # Path to your ARM template # # Define parameters inline # $parameters = @{ # "Action_Group_Name" = "QuotaAlertRules-AG-2" # "Action_Group_ShortName" = "QuotaAlert2" # "Email_Address" = "[email protected]" # } # # Deploy the template # New-AzResourceGroupDeployment ` # -ResourceGroupName $resourceGroupName ` # -TemplateFile $templateFilePath ` # -TemplateParameterObject $parameters ` # -DeploymentName $deploymentName
Below is the output after deploying Azure ARM template with parameters files from PowerShell Az module. All the resources are created successfully with this command on the Azure Cloud.
Here is ARM template in JSON format to deploy Action Group and Schedule Query rule for subscription. There are few items I marked in red inside the KUSTO query language, which you need to modify accordingly as per your infrastructure. If you want to totally automate values inside Kusto, you can make use of templating to create a template from required values.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "Action_Group_Name": { "defaultValue": "Action_Group01", "type": "string" }, "Action_Group_ShortName": { "defaultValue": "actiongroup", "type": "string" }, "Email_Address": { "defaultValue": "[email protected]", "type": "string" }, "Quota_Alert_Name": { "defaultValue": "Quota_Alert01", "type": "string" }, "User_Managed_Identity": { "defaultValue": "/subscriptions/9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vcloud-lab.com/providers/Microsoft.ManagedIdentity/userAssignedIdentities/dev", "type": "string" }, "Scopes": { "defaultValue": "/subscriptions/9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "type": "string" }, "Dimensions_Type": { "defaultValue": "microsoft.compute/locations/usages", "type": "string" }, "Dimensions_Location": { "defaultValue": "eastus", "type": "string" }, "Dimensions_Quota_Name": { "defaultValue": "cores", "type": "string" } }, "variables": {}, "resources": [ { "type": "microsoft.insights/actionGroups", "apiVersion": "2023-09-01-preview", "name": "[parameters('Action_Group_Name')]", "location": "Global", "properties": { "groupShortName": "[parameters('Action_Group_ShortName')]", "enabled": true, "emailReceivers": [ { "name": "EmailAction", "emailAddress": "[parameters('Email_Address')]", "useCommonAlertSchema": true } ], "smsReceivers": [], "webhookReceivers": [], "eventHubReceivers": [], "itsmReceivers": [], "azureAppPushReceivers": [], "automationRunbookReceivers": [], "voiceReceivers": [], "logicAppReceivers": [], "azureFunctionReceivers": [], "armRoleReceivers": [ { "name": "EmailARMRole", "roleId": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635", "useCommonAlertSchema": true } ] } }, { "type": "microsoft.insights/scheduledqueryrules", "apiVersion": "2023-03-15-preview", "name": "[parameters('Quota_Alert_Name')]", "location": "[parameters('Dimensions_Location')]", "identity": { "type": "UserAssigned", "userAssignedIdentities": { "[parameters('User_Managed_Identity')]": {} } }, "properties": { "severity": 4, "enabled": true, "evaluationFrequency": "PT15M", "scopes": [ "[parameters('Scopes')]" ], "windowSize": "PT15M", "criteria": { "allOf": [ { "query": "arg(\"\").QuotaResources \n| where subscriptionId =~ '9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'\n| where type =~ 'microsoft.compute/locations/usages'\n| where isnotempty(properties)\n| mv-expand propertyJson = properties.value limit 400\n| extend\n usage = propertyJson.currentValue,\n quota = propertyJson.['limit'],\n quotaName = tostring(propertyJson.['name'].value)\n| extend usagePercent = toint(usage)*100 / toint(quota)| project-away properties| where location in~ ('eastus')| where quotaName in~ ('cores')", "timeAggregation": "Maximum", "metricMeasureColumn": "usagePercent", "dimensions": [ { "name": "type", "operator": "Include", "values": [ "[parameters('Dimensions_Type')]" ] }, { "name": "location", "operator": "Include", "values": [ "[parameters('Dimensions_Location')]" ] }, { "name": "quotaName", "operator": "Include", "values": [ "[parameters('Dimensions_Quota_Name')]" ] } ], "operator": "GreaterThanOrEqual", "threshold": 80, "failingPeriods": { "numberOfEvaluationPeriods": 1, "minFailingPeriodsToAlert": 1 } } ] }, "actions": { "actionGroups": [ "[resourceId('microsoft.insights/actionGroups', parameters('Action_Group_Name'))]" ] } } } ] } |
This is ARM parameters file, If you don't want to use separate ARM parameters file. You can mention them in the PowerShell parameters Object as shown in the above PS option 2 example.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "Action_Group_Name": { "value": "Action_Group01" }, "Action_Group_ShortName": { "value": "actiongroup" }, "Email_Address": { "value": "[email protected]" }, "Quota_Alert_Name": { "value": "Quota_Alert01" }, "User_Managed_Identity": { "value": "/subscriptions/9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vcloud-lab.com/providers/Microsoft.ManagedIdentity/userAssignedIdentities/dev" }, "Scopes": { "value": "/subscriptions/9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }, "Dimensions_Type": { "value": "microsoft.compute/locations/usages" }, "Dimensions_Location": { "value": "eastus" }, "Dimensions_Quota_Name": { "value": "cores" } } } |
After deployment completed you can see two resources are create Action Group and Log search alert rule (Schedule query rule).
Useful Articles
Terraform variable multiple validation advanced blocks example
Terraform variable type list with for_each for loop examples
Terraform convert single string to list or set
Terraform workspaces with example
Terraform map of object for loop with if condition example
Terraform for_each for loop list of object without count example
Terraform using for loop in attribute value without for_each
Part 0: HashiCorp HCP Terraform Cloud backend configuration
Part 1: Create GitHub repository and branches using Terraform
Part 2 Terraform modules using a github.com repository as a source
Part 3 Automating and Planning Azure Resources with Terraform and GitHub Actions
Part 4 GitHub Actions deploy azure resources with Terraform backend
Part 4.1 GitHub Actions deploy azure resources with PowerShell
Part 4.2 GitHub Actions manage Microsoft Azure Cloud with az CLI
Azure OIDC OpenID Connect password less with GitHub Actions
GitHub repository integration with Terraform Cloud to Deploy and Manage Azure
Resolved Terraform Error: POST https api.github.com user repos 401 Requires authentication
Azure DevOps Enable creation of classic build release pipelines grayed out
Adding parameters in Azure DevOps pipelines examples Part 1
Azure Web App Containers Cannot perform credential operations for providers Microsoft.ContainerRegistry ad admin user is disabled, enable it