I have a Terraform locals.tf
file like the below snippet, which contains my environment definition.
locals {
environments = [
"dev",
"test",
"preprod",
"prod"
]
}
I am now looking to create an identical resource, an Azure monitor metric alert in this case, for each of the listed environments (except prod). I am attempting to do so using a For_Each
loop in the resource block of my main.tf
file, a snippet of which is shown below:
resource "azurerm_monitor_metric_alert" "main" {
for_each = {
[for s in toset(local.environments) : if s != "prod"]
}
name = "${each.key}-metric-alert"
resource_group_name = azurerm_resource_group.rg.name
scopes = [azurerm_storage_account.to_monitor[each.key].id]
[..........ADDITIONAL NON-PROD RESOURCE CONFIG...........]
For the prod environment though, the monitor alert requires a slightly different set of configuration from the others, and so what I'd like to do is filter out that environment from the locals.tf
file and then using another azurerm_monitor_metric_alert resource block, configure it along the lines of the below snippet:
resource "azurerm_monitor_metric_alert" "main" {
for_each = {
[for s in toset(local.environments) : if s == "prod"]
}
name = "${each.key}-metric-alert"
resource_group_name = azurerm_resource_group.rg.name
scopes = [azurerm_storage_account.to_monitor[each.key].id]
[..........ADDITIONAL PROD CONFIG...........]
I have the tried the above and various other implementations, but unfortunately I simply can't get this to work. Would greatly appreciate some assistance here.
So thanks to the wonderful contribution of Martin Atkins, coupled with some further research and experiments, I managed to successfully construct my solution mainly by way of the following file updates which may help others in future:
locals {
environments = toset([
"dev",
"test",
"preprod",
"prod",
])
}
resource "azurerm_monitor_action_group" "non-prod" {
for_each = {for p in toset(local.environments): p => p if p != "prod" }
name = "${each.key}-actiongroup"
resource_group_name = azurerm_resource_group.rg.name
short_name = "non-prod-acg"
webhook_receiver {
name = "callmyapi"
service_uri = "http://example.com/alert"
}
email_receiver {
name = "John Doe"
email_address = "jdoe@myemail.com"
}
}
resource "azurerm_monitor_metric_alert" "non-prod" {
for_each = {for p in toset(local.environments): p => p if p != "prod" }
name = "${each.key}-metric-alert"
resource_group_name = azurerm_resource_group.rg.name
scopes = [azurerm_storage_account.to_monitor[each.key].id]
description = "each.value.description"
criteria {
metric_namespace = "Microsoft.Storage/storageAccounts"
metric_name = "Transactions"
aggregation = "Total"
operator = "GreaterThan"
threshold = 50
dimension {
name = "ApiName"
operator = "Include"
values = ["*"]
}
}
action {
action_group_id = azurerm_monitor_action_group.non-prod[each.key].id
}
}
resource "azurerm_monitor_action_group" "prod" {
for_each = {for p in toset(local.environments): p => p if p == "prod" }
name = "${each.key}-actiongroup"
resource_group_name = azurerm_resource_group.rg.name
short_name = "prod-acg"
webhook_receiver {
name = "callmyapi"
service_uri = "http://example.com/alert"
}
email_receiver {
name = "D Smith"
email_address = "dsmith44@myemail.com"
}
}
resource "azurerm_monitor_metric_alert" "prod" {
for_each = {for p in toset(local.environments): p => p if p == "prod" }
name = "${each.key}-metric-alert"
resource_group_name = azurerm_resource_group.rg.name
scopes = [azurerm_storage_account.to_monitor[each.key].id]
description = "${each.key} - Action will be triggered when Transactions count is greater than 60"
criteria {
metric_namespace = "Microsoft.Storage/storageAccounts"
metric_name = "Transactions"
aggregation = "Total"
operator = "GreaterThan"
threshold = 60
dimension {
name = "ApiName"
operator = "Include"
values = ["*"]
}
}
action {
action_group_id = azurerm_monitor_action_group.prod[each.key].id
}
}