No more than 1 "maintenance_policy" blocks are allowed

I am trying to build a dynamic block for a Redis instance (google provider), but I keep getting this error while planning. Here is the code:
variables.tf

variable "redis_maintenance_policy" {
    type = object({
        description = string,
        weekly_maintenance_window = object({
            day = string,
            start_time = object({
                hours   = number,
                minutes = number,
                nanos   = number,
                seconds = number,
            })
        })
    })
}

in the main.tf I have the following code:

  dynamic maintenance_policy {
    for_each = var.redis_maintenance_policy
    iterator = policy
    content {
        description = policy.value.description
        weekly_maintenance_window {
            day = policy.value.weekly_maintenance_window.day
            start_time {
                hours   = policy.value.weekly_maintenance_window.start_time.hours
                minutes = policy.value.weekly_maintenance_window.start_time.minutes
                nanos   = policy.value.weekly_maintenance_window.start_time.nanos
                seconds = policy.value.weekly_maintenance_window.start_time.seconds
            }
        }
    }
  }

No matter how I change this, I keep receiving the following errors:

│ Error: Too many maintenance_policy blocks
│ 
│   on main.tf line 44, in resource "google_redis_instance" "cache":
│   44:     content {
│ 
│ No more than 1 "maintenance_policy" blocks are allowed
╵
╷
│ Error: Unsupported attribute
│ 
│   on main.tf line 45, in resource "google_redis_instance" "cache":
│   45:         description = policy.value.description
│     ├────────────────
│     │ policy.value is "Maintenance policy description here"
│ 
│ Can't access attributes on a primitive-typed value (string).

Any clues why for_each is thinking I have more than 1 object? And also why its not accessing the description variable?

Thank you in advance!

Hi @ricardolopes86,

var.redis_maintenance_policy is a single object, so when you use that as an argument to for_each you are attempting to create a block for each attribute of that object. This is why you are getting an error about multiple blocks, (there are 2 attributes), and the first attribute is description, which is why policy.value is the description string.

If you want to create a dynamic block with a single element, that single element needs to be contained in a list for for_each to iterate over. Since you know you want to create exactly one block here though, there is no need for dynamic at all, just assign the object values to the desired attributes.

  maintenance_policy {
    description = var.redis_maintenance_policy.description
    weekly_maintenance_window {
      day = var.redis_maintenance_policy.weekly_maintenance_window.day
      start_time {
        hours   = var.redis_maintenance_policy.weekly_maintenance_window.start_time.hours
        minutes = var.redis_maintenance_policy.weekly_maintenance_window.start_time.minutes
        nanos   = var.redis_maintenance_policy.weekly_maintenance_window.start_time.nanos
        seconds = var.redis_maintenance_policy.weekly_maintenance_window.start_time.seconds
      }
    }
  }

I ended up using something similar. But still using dynamic block.