Menu

Virtual Geek

Tales from real IT system administrators world and non-production environment

Deploy CPU quota usage alerts for subscription using Terraform azapi provider

This is another way of deploying resources/services on Azure using azapi provider using HashiCorp Terraform.

AzAPI is a lightweight, flexible provider that leverages the Azure ARM REST APIs, empowering you to manage any Azure resource type with any desired API version. This enables access to the latest Azure features and functionality.
Key Benefits:
Compatibility with any API version
Designed for standalone use or combined deployments
Seamless integration with AzureRM provider
Comprehensive resource management capabilities

AzAPI: A Powerful, Versatile Solution
AzAPI is a first-class provider that offers unparalleled flexibility and control over Azure resources, making it an ideal choice for:
Streamlining resource deployment and management
Leveraging cutting-edge Azure features
Managing complex Azure environments

Below is the output of Subscription Quota Alert deployment.

  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
terraform apply --auto-approve  
data.azurerm_subscription.subscriptioninfo: Reading...
data.azurerm_resource_group.rginfo: Reading...
data.azurerm_subscription.subscriptioninfo: Read complete after 1s [id=/subscriptions/9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx]
data.azurerm_resource_group.rginfo: Read complete after 1s [id=/subscriptions/9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vcloud-lab.com]
data.azurerm_user_assigned_identity.uaiinfo: Reading...
data.azurerm_user_assigned_identity.uaiinfo: Read complete after 1s [id=/subscriptions/9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vcloud-lab.com/providers/Microsoft.ManagedIdentity/userAssignedIdentities/dev]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # azapi_resource.action_group will be created
  + resource "azapi_resource" "action_group" {
      + body                      = jsonencode(
            {
              + properties = {
                  + armRoleReceivers           = [
                      + {
                          + name                 = "EmailARMRole"
                          + roleId               = "8e3af657-a8ff-443c-a75c-2fe8c4bcb635"
                          + useCommonAlertSchema = true
                        },
                    ]
                  + automationRunbookReceivers = []
                  + azureAppPushReceivers      = []
                  + azureFunctionReceivers     = []
                  + emailReceivers             = [
                      + {
                          + emailAddress         = "[email protected]"
                          + name                 = "EmailAction"
                          + useCommonAlertSchema = true
                        },
                    ]
                  + enabled                    = true
                  + eventHubReceivers          = []
                  + groupShortName             = "AG01"
                  + itsmReceivers              = []
                  + logicAppReceivers          = []
                  + smsReceivers               = []
                  + voiceReceivers             = []
                  + webhookReceivers           = []
                }
            }
        )
      + id                        = (known after apply)
      + ignore_casing             = false
      + ignore_missing_property   = true
      + location                  = "Global"
      + name                      = "Action_Group_01"
      + output                    = (known after apply)
      + parent_id                 = "/subscriptions/9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vcloud-lab.com"
      + removing_special_chars    = false
      + schema_validation_enabled = true
      + type                      = "Microsoft.Insights/actionGroups@2023-09-01-preview"
    }

  # azapi_resource.scheduled_query_rule will be created
  + resource "azapi_resource" "scheduled_query_rule" {
      + body                      = (known after apply)
      + id                        = (known after apply)
      + ignore_casing             = false
      + ignore_missing_property   = true
      + location                  = "eastus"
      + name                      = "quota_alert_01"
      + output                    = (known after apply)
      + parent_id                 = "/subscriptions/9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vcloud-lab.com"
      + removing_special_chars    = false
      + schema_validation_enabled = true
      + tags                      = (known after apply)
      + type                      = "Microsoft.Insights/scheduledqueryrules@2023-03-15-preview"

      + identity {
          + identity_ids = [
              + "/subscriptions/9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vcloud-lab.com/providers/Microsoft.ManagedIdentity/userAssignedIdentities/dev",
            ]
          + principal_id = (known after apply)
          + tenant_id    = (known after apply)
          + type         = "UserAssigned"
        }
    }

Plan: 2 to add, 0 to change, 0 to destroy.
Plan: 2 to add, 0 to change, 0 to destroy.
Plan: 2 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + name = (known after apply)
azapi_resource.action_group: Creating...
azapi_resource.action_group: Creation complete after 8s [id=/subscriptions/9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vcloud-lab.com/providers/Microsoft.Insights/actionGroups/Action_Group_01]
azapi_resource.scheduled_query_rule: Creating...
azapi_resource.scheduled_query_rule: Still creating... [10s elapsed]
azapi_resource.scheduled_query_rule: Creation complete after 19s [id=/subscriptions/9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vcloud-lab.com/providers/Microsoft.Insights/scheduledqueryrules/quota_alert_01]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Outputs:

name = "/subscriptions/9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vcloud-lab.com/providers/Microsoft.Insights/actionGroups/Action_Group_01"

Related Articles:
Create CPU quota usage alerts for subscription using Azure ARM templates
Configure CPU quota usage alerts for subscription using Azure Bicep templates

Below is the complete terraform configuration code which usage combination of azapi and azurerm provider to create resources on Azure.

Download this script terraform_az_api_subscription_quota_alert_action_group_scheduled_quota.tf here or it is also available on github.com.

  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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
terraform {
  required_providers {
    azapi = {
      source = "azure/azapi"
      # version = "1.8.0"  # Use the latest version or whichever is stable
    }
    azurerm = {
      source = "hashicorp/azurerm"
    }
  }
}

provider "azapi" {
  # Optionally configure provider settings here
}

provider "azurerm" {
  features {}
  subscription_id = "9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

###########################################################

variable "resource_group_name" {
  description = "Resource Group Name"
  type        = string
  default     = "vcloud-lab.com"
}

variable "action_group_name" {
  description = "The name of the action group"
  type        = string
  default     = "Action_Group_01"
}

variable "action_group_short_name" {
  description = "The short name of the action group"
  type        = string
  default     = "AG01"
}

variable "email_address" {
  description = "The email address to use for email alerts"
  type        = string
  default     = "[email protected]"
}

variable "quota_alert_name" {
  description = "Provide Quota alert name"
  type        = string
  default     = "quota_alert_01"
}

variable "dimensions_type" {
  type        = string
  description = "Provide Dimensions Type for Scheduled Query Rule"
  default     = "microsoft.compute/locations/usages"
}

variable "dimensions_quota_name" {
  type        = string
  description = "Provide Dimensions name for Scheduled Query Rule"
  default     = "cores"
}

######################################################

data "azurerm_subscription" "subscriptioninfo" {}

data "azurerm_resource_group" "rginfo" {
  name = var.resource_group_name
}

data "azurerm_user_assigned_identity" "uaiinfo" {
  name                = "dev"
  resource_group_name = data.azurerm_resource_group.rginfo.name
}

######################################################

locals {
  scopeInfo = "/subscriptions/${data.azurerm_subscription.subscriptioninfo.subscription_id}"
  # format("%s/%s","/subscriptions/","data.azurerm_subscription.subscriptioninfo.subscription_id)
}

######################################################

#https://learn.microsoft.com/en-us/azure/templates/microsoft.insights/actiongroups?pivots=deployment-language-terraform

resource "azapi_resource" "action_group" {
  type      = "Microsoft.Insights/actionGroups@2023-09-01-preview"
  name      = var.action_group_name
  location  = "Global"
  parent_id = data.azurerm_resource_group.rginfo.id

  body = jsonencode({
    properties = {
      groupShortName = var.action_group_short_name
      enabled        = true

      emailReceivers = [
        {
          name                 = "EmailAction"
          emailAddress         = var.email_address
          useCommonAlertSchema = true
        }
      ]

      smsReceivers               = []
      webhookReceivers           = []
      eventHubReceivers          = []
      itsmReceivers              = []
      azureAppPushReceivers      = []
      automationRunbookReceivers = []
      voiceReceivers             = []
      logicAppReceivers          = []
      azureFunctionReceivers     = []

      armRoleReceivers = [
        {
          name                 = "EmailARMRole"
          roleId               = "8e3af657-a8ff-443c-a75c-2fe8c4bcb635"
          useCommonAlertSchema = true
        }
      ]
    }
  })
}

# https://learn.microsoft.com/en-us/azure/templates/microsoft.insights/scheduledqueryrules?pivots=deployment-language-terraform


resource "azapi_resource" "scheduled_query_rule" {
  type      = "Microsoft.Insights/scheduledqueryrules@2023-03-15-preview"
  name      = var.quota_alert_name
  location  = data.azurerm_resource_group.rginfo.location
  parent_id = data.azurerm_resource_group.rginfo.id

  identity {
    type         = "UserAssigned"
    identity_ids = [data.azurerm_user_assigned_identity.uaiinfo.id]
  }

  body = jsonencode({
    properties = {
      severity            = 4
      enabled             = true
      evaluationFrequency = "PT15M"
      scopes              = [local.scopeInfo]
      windowSize          = "PT15M"

      criteria = {
        allOf = [
          {
            query               = format("arg('').QuotaResources | where subscriptionId =~ '%s' | where type =~ 'microsoft.compute/locations/usages' | where isnotempty(properties) | mv-expand propertyJson = properties.value limit 400 | extend usage = propertyJson.currentValue, quota = propertyJson['limit'], quotaName = tostring(propertyJson['name'].value) | extend usagePercent = toint(usage)*100 / toint(quota) | project-away properties | where location in~ ('%s') | where quotaName in~ ('%s')", data.azurerm_subscription.subscriptioninfo.subscription_id, data.azurerm_resource_group.rginfo.location, var.dimensions_quota_name)
            timeAggregation     = "Maximum"
            metricMeasureColumn = "usagePercent"

            # Dimensions Configuration
            dimensions = [
              {
                name     = "type"
                operator = "Include"
                values   = [var.dimensions_type]
              },
              {
                name     = "location"
                operator = "Include"
                values   = [data.azurerm_resource_group.rginfo.location]
              },
              {
                name     = "quotaName"
                operator = "Include"
                values   = [var.dimensions_quota_name]
              }
            ]

            operator  = "GreaterThanOrEqual"
            threshold = 80

            failingPeriods = {
              numberOfEvaluationPeriods = 1
              minFailingPeriodsToAlert  = 1
            }
          }
        ]
      }

      actions = {
        actionGroups = [azapi_resource.action_group.id]
      }
    }
  })
}

output "name" {
  value = azapi_resource.action_group.id
}

This is the output of the resource group where Action Group and Log Search alert rule (Scheduled query rule) is deployed.

Azure ARM Templates azure cloud deployment automation PowerShell user assigned Identity log search alert quota alert action group subscription quota alert CPU usage and quota region location configuration.png

Useful Articles
Microsoft Azure Virtual WAN Part 1 - Create Virtual Network and subnets
Part 2 Create a Virtual WAN (VWAN) on Azure Portal
Microsoft Azure Virtual WAN Part 3 - Create secured virtual hub inside VWAN
Microsoft Azure Virtual WAN Part 3.1 - Create secured virtual hub inside Azure Firewall Manager
Microsoft Azure Virtual WAN Part 4 - Add Virtual Network connection | Hub vNet Peering
Microsoft Azure Virtual WAN Part 5 - Create Azure Virtual Machine (VM)
Microsoft Azure Virtual WAN Part 6 - Creating and configuring Azure Firewall Policies
Microsoft Azure Virtual WAN Part 7 - Configure security configuration | Route traffic to your secured hub | Test connectivity
Using terraform to clone a virtual machine on VMware vSphere infrastructure
Terraform module clone VMware vSphere Linux and Windows virtual machine
Terraform VMware vSphere Virtual Machine customization clone failed on Windows
Terraform VMware vSphere Virtual Machine cloning Operating system not found

Go Back

Comment

Blog Search

Page Views

12597597

Follow me on Blogarama