Hi All, I am trying to figure out how to pass this json to for_each in my resource . But I have not been able to get the nested for loop working as for_each
expect the map or string as input.
[
{
"service": "popcorn",
"sad": "Name",
"alerts": [
{
"sev": 3,
"value": [
"B1",
"B2",
"B3"
]
}
]
},
{
"service": "donuts",
"sad": "Value",
"alerts": [
{
"sev": 1,
"value": [
"B4",
"B5"
]
},
{
"sev": 3,
"value": [
"B7",
"B8",
"B9"
]
},
{
"sev": 4,
"value": [
"B10",
"B11",
"B12",
"B13"
]
}
]
}
]
My end goal is to have sev as unique values to loop over alerts array in each service json inside. So ideally first for loop to have unique service and then inside that for loop for unique value for sev .
You can use it like this,
# first loop
for_each = { for object in var.object_array: object.service => object }
service = eack.key
sad = each.value.sad
# 2nd loop
for_each = { for alert in each.value.alerts: alert.sev => alert }
Thanks @Sreerag74031 . But How do I combine this into a single for_each
with nested for loops. As I have to use this into a single resource. I can do something like below and this json_data can have a structure. But still I should be able to use nested for loop ?
I think @apparentlymart did gave a nested for loop solution , I can’t think of how this data can be evaluated.
locals { json_data = jsondecode(file(var.object_array)) }
Number of alert config is based on the alerts array, so i assume you are using a dynamic block. and the second for_each will be inside dynamic block.
# first loop
for_each = { for object in var.object_array: object.service => object }
service = eack.key
sad = each.value.sad
dynamic "alert" {
# 2nd loop
for_each = { for el in each.value.alerts: el.sev => el }
content {
sev = alert.key
value = alert.value.value
}
}
Thanks much @Sreerag74031 I will try this now. Also I am thinking would I be able to use each.key
inside dyanamic block ?
2nd loop inside a resource you may need to use dynamic block. it also depends on the resource configuration. if you could share the provider resource config documentation or link.
sure , I have this resource that I am trying to use , https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/monitor_scheduled_query_rules_alert
Also to give you more detail , I have to parse that above json in such a way that outer loop and inner loop output to be able to pass both innner and outer loop values to be used inside this resource.
would you be able to share current tf config you have for this resource.
I sent you whole config in the message.
could you share the values_file file format, want to see the variable names.
Also if i understand you wanted to create one azurerm_monitor_scheduled_query_rules_alert resource for each alert object, is that correct?
yes this resource should create each alert object and use the other outer loop values.
See if this works
locals {
json_data = flatten([for svc in jsondecode(file("values.json")) :
[for alert in svc.alerts :
{
"service" = svc.service
"pivoted_field" = svc.pivoted_field
"frequency" = alert.frequency
"severity" = alert.severity
"values" = alert.values
}
]
])
}
resource "azurerm_monitor_scheduled_query_rules_alert" "log_alerts" {
for_each = local.json_data
name = format("%s-%s-severity-%s-queryrule", var.prefix, each.value.service, each.value.severity)
location = var.location
resource_group_name = var.resource_group
action {
action_group = var.action_group
email_subject = var.email_subject
custom_webhook_payload = var.custom_webhook_payload
}
data_source_id = var.data_source_id
description = format("severity %s alert for %s", each.value.severity, each.value.service)
enabled = true
query = ""
severity = each.value.severity
frequency = each.value.frequency
time_window = each.value.frequency
trigger {
operator = "GreaterThan"
# Threshold value
threshold = 0
metric_trigger {
## Trigger Alert Based On
metric_trigger_type = "Consecutive" # breaches
operator = "GreaterThan"
threshold = 0
## Aggregate on
metric_column = "${each.value.pivoted_field},Namespace"
}
}
}