I am trying to set up alerts in Azure bicep resources/modules. The goal is to have 3 files, one where the initial resource structure is created and parameterized:
param metricAlertsName string
param description string
param severity int
param enabled bool = true
param scopes array = []
param evaluationFrequency string
param windowSize string
param targetResourceRegion string = resourceGroup().location
param allOf array = []
param actionGroupName string
var actionGroupId = resourceId(resourceGroup().name, 'microsoft.insights/actionGroups', actionGroupName)
resource dealsMetricAlerts 'Microsoft.Insights/metricAlerts@2018-03-01' = [for appService in appServices : {
name: metricAlertsName
location: 'global'
tags: {}
properties: {
description: description
severity: severity
enabled: enabled
scopes: scopes
evaluationFrequency: evaluationFrequency
windowSize: windowSize
targetResourceRegion: targetResourceRegion
criteria: {
'odata.type': 'Microsoft.Azure.Monitor.SingleResourceMultipleMetricCriteria'
allOf: allOf
}
actions: [
{
actionGroupId: actionGroupId
}
]
}
}]
A second file, main.bicep where all of my resources are being consumed as modules:
module dealsMetricAlerts '../modules/management/metric-alert.bicep' = [for (alert, index) in alertConfig.metricAlerts: {
name: alert.name
params: {
metricAlertsName: alert.params.metricAlertsName
actionGroupName: actionGroupName
description: alert.params.description
evaluationFrequency: alert.params.evaluationFrequency
severity: alert.params.severity
windowSize: alert.params.windowSize
allOf: alert.params.allOf
scopes: [
resourceId(resourceGroup().name,'Microsoft.Web/sites', 'gbt-${env1}-${env}-${location}-webapp')
]
}
}]
And the third file which is a parameter file in which I can loop over, enter its values into the module in main.bicep to create multiple resources without having to write more than one module:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"alertConfig": {
"value": {
"metricAlerts": [
{
"name": "403ErrorTest",
"params": {
"metricAlertsName": "AppService403ErrorTest",
"actionGroupName": "actionGroupName",
"description": "Alert fires whenever the App Service throws a 403 error",
"evaluationFrequency": "PT5M",
"severity": 2,
"windowSize": "PT15M",
"allOf": [
{
"name": "403errorTest",
"metricName": "Http403",
"dimensions": [],
"operator": "GreaterThan",
"threshold": 0,
"timeAggregation": "Count"
}
]
}
},
{
"name": "5XXErrorTest",
"params": {
// Values for 500 error
}
}
]
}
}
}
}
I have a total of 5 app services, 1 web app and 4 function apps. If I was to hard code the name of the app service like above then that one web app is deployed with the 2 errors exactly as it should.
The issue that I'm having is to try and use another loop on the scopes param to have the 2 errors attached to all 5 app services.
I tried something like:
// Created an array with the names of the app services
var appServices = [
'dda-webApp'
'dealservice-fnapp'
'itemdata-fnapp'
'refdata-fnapp'
'userprofile-fnapp'
]
// Update the scopes param to loop through the names\
scopes: [for appService in appServices: [
resourceId(resourceGroup().name,'Microsoft.Web/sites', 'gbt-${env1}-${env}-${location}-${appService}')
]]
This most often gives me an error saying: Unexpected token array in scopes[0]
.
I believe what's happening is when it's trying to look up the resource by name in resourceId it's looping through all of the appServices names and attaching the entire array onto the resource name making it invalid.
Is there another way to loop through these scopes in order to attach the 403 and 500 alerts to each of my 5 app services?