How iterate a list object over list object

Hi everyone,

I’m working a project and I need create a
azurerm_monitor_diagnostic_setting with terraform:

resource "azurerm_monitor_diagnostic_setting" "default" {
  for_each = { for o in local.test: o.action_group => o }
  name               = each.value.monitoring.name
  target_resource_id = "${element(values(azurerm_storage_account.default)[*].id, length(var.storage_accounts))}/blobServices/default"
  storage_account_id = element(values(azurerm_storage_account.default)[*].id, length(var.storage_accounts))

  dynamic "metric" {
    for_each = try(each.value.monitoring.metric, [])
    content {
      category = lookup(metric.value, "category", "Transaction")
      enabled  = lookup(metric.value, "enabled", true)
      dynamic "retention_policy" {
        for_each = metric.value["retention_policy"]
        content {
          enabled = lookup(retention_policy.value, "enabled", true)
          days    = lookup(retention_policy.value, "days", "5")
        }
      }
    }
  } 

  dynamic "enabled_log" {
    for_each = try(each.value.monitoring.log, [])
    content {
      category       = lookup(log.value, "category", "StorageRead")
      category_group = lookup(log.value, "category_group", "null")
      dynamic "retention_policy" {
        for_each = try(each.value.monitoring.retention_policy, [])
        content {
          enabled = lookup(retention_policy.value, "enabled", true)
          days    = lookup(retention_policy.value, "days", "5")
        }
      }
    }
  } 

  depends_on = [
    azurerm_storage_blob.default
  ]
}

I configured the following variable file:

variables.tf

variable "storage" {
  type        = list(object({
    name                   = optional(string)
    storage_account_name   = optional(string)
    storage_container_name = optional(string)
    resource_group_name  = optional(string)
    type                   = optional(string)

    source = optional(string)
    size = optional(number)
    content_type = optional(string)
    parallelism = optional(number)
    access_tier = optional(string)
    metadata = optional(map(string))

    location           = optional(string)

    monitoring = optional(list(object({
      action_group_name = optional(string)
      resource_group_name = optional(string)
      scopes              = optional(string)
      frequency   = optional(string)
      severity    = optional(number)
      window_size = optional(string)

      metric = optional(list(object({
        category = optional(string)
        enabled  = optional(bool)
        retention_policy = optional(list(object({
          enabled = optional(bool)
          days    = optional(number)
        })))
      })))
 
      log = optional(list(object({
        category = optional(string)
        category_group  = optional(bool)
        retention_policy = optional(list(object({
          enabled = optional(bool)
          days    = optional(number)
        })))
      })))

      criteria = optional(list(object({
        metric_namespace = optional(string)
        metric_name      = optional(string)
        aggregation      = optional(string)
        operator         = optional(string)
        threshold        = optional(number)
        skip_metric_validation = optional(bool)
        dimension = optional(list(object({
          name     = optional(string)
          operator = optional(string)
          values   = optional(list(string))
        })))
      })))
  }))
  description = "(Optional) Map of key/value to create `Storage`."
  default     = []
}

locals.tf

locals {
  test = flatten([
    for k, v in var.storage : [
      for n, s in v.monitoring : {
        name = s.name
        action_group = s.action_group_name
        resource_group = s.resource_group_name
      }
     ]
  ])
}

The output of locals

 + test    = [
      + [
          + {
              + action              = null
              + action_group_name   = "action-group-01"
              + criteria            = null
              + dynamic_criteria    = null
              + frequency           = null
              + log                 = [
                  + {
                      + category         = "StorageRead"
                      + category_group   = null
                      + retention_policy = [
                          + {
                              + days    = 15
                              + enabled = true
                            },
                        ]
                    },
                  + {
                      + category         = "StorageWrite"
                      + category_group   = null
                      + retention_policy = [
                          + {
                              + days    = 15
                              + enabled = true
                            },
                        ]
                    },
                  + {
                      + category         = "StorageDelete"
                      + category_group   = null
                      + retention_policy = [
                          + {
                              + days    = 15
                              + enabled = true
                            },
                        ]
                    },
                ]
              + metric              = [
                  + {
                      + category         = "Transaction"
                      + enabled          = true
                      + retention_policy = [
                          + {
                              + days    = 15
                              + enabled = true
                            },
                        ]
                    },
                ]
              + name                = "my-rule"
              + resource_group_name = "rg-test"
              + scopes              = null
              + severity            = null
              + window_size         = null
            },
          + {
              + action              = null
              + action_group_name   = "action-group-02"
              + criteria            = null
              + dynamic_criteria    = null
              + frequency           = null
              + log                 = null
              + metric              = null
              + name                = "my-rule-01"
              + resource_group_name = "rg-test"
              + scopes              = null
              + severity            = null
              + window_size         = null
            },
        ],
    ]

I need to obtain into storage list object, the lists objects, to configure azurerm_monitor_diagnostic_setting:

  • log
  • metrics

main.tf

My storage.tf

storage = [
    {
      name = var.storage_name
      storage_account_name = var.storage_account_name
      storage_container_name = var.storage_container_name
      resource_group_name = module.resource_group.name["demo_01"]
      location = var.location
      type = var.type
      tags = var.tags
 
      monitoring = [
        {
          name = "my-rule"
          resource_group_name = module.resource_group.name["demo_01"]
          action_group_name = "action-group-01"

          metric = [
            {
              category = "Transaction"
              enabled = true
              retention_policy = [
                {
                  enabled = true
                  days = 15
                }
              ]
            }
          ]

          log = [
            {
              category = "StorageRead"
              enabled = true
              retention_policy = [
                {
                  enabled = true
                  days = 15
                }
              ]
            },
            {
              category = "StorageWrite"
              enabled = true
              retention_policy = [
                {
                  enabled = true
                  days = 15
                }
              ]
            },
            {
              category = "StorageDelete"
              enabled = true
              retention_policy = [
                {
                  enabled = true
                  days = 15
                }
              ]
            }
          ]
        },

        },
        {          
          name = "my-rule-02"
          resource_group_name = module.resource_group.name["demo_01"]
          action_group_name = "action-group-02"
        },
      ]
    }
  ]

When I run my code, I received this error:

│ Error: Unsupported attribute
│
│   on .terraform/modules/storage/blob-storage.tf line 62, in resource "azurerm_monitor_diagnostic_setting" "default":
│   62:   for_each = { for o in local.teste : o.action_group => o }
│
│ Can't access attributes on a list of objects. Did you mean to access an attribute for a specific element of the list, or across all elements of the list?

My question is it possible to get a list object into a list object if possible can anyone send me a hint how to get this data.

I’m grateful for any tip or help