skip to Main Content

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,
            })
        })
    })

    default = {
        description = "Maintenance policy description here",
        weekly_maintenance_window = {
            day = "TUESDAY",
            start_time = {
                hours   = 0,
                minutes = 30,
                nanos   = 0,
                seconds = 0,
            }
        }
    }
}

Then I tried to create the dynamic block by using like this:
main.tf

resource "google_redis_instance" "cache" {
  auth_enabled            = false
  authorized_network      = data.google_compute_network.gcp-network.id
  connect_mode            = "PRIVATE_SERVICE_ACCESS"
  display_name            = var.redis_display_name

  labels = var.redis_labels

  memory_size_gb          = var.redis_memory_size_gb
  name                    = var.redis_name
  project                 = var.redis_project
  read_replicas_mode      = var.redis_read_replicas_mode
  redis_configs           = var.redis_configs
  redis_version           = var.redis_version
  region                  = var.redis_region
  replica_count           = var.redis_replica_count
  reserved_ip_range       = var.redis_reserved_ip_range
  secondary_ip_range      = var.redis_secondary_ip_range
  tier                    = var.redis_tier
  transit_encryption_mode = "DISABLED"

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.start_time.hours
                minutes = policy.value.start_time.minutes
                nanos   = policy.value.start_time.nanos
                seconds = policy.value.start_time.seconds
              }
            }
          }
        }
  }
depends_on = [google_service_networking_connection.private_service_connection]

}

It keeps giving me lots of 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).
╵

I already tried to make dynamic block for each of the nested object, same problem. I also tried to flatten the object and see if I could access it locally. No success as well.

Any hints on what I am doing wrong here?

2

Answers


  1. Chosen as BEST ANSWER

    With the answer from @Marko, I was able to find a solution.

    dynamic maintenance_policy {
        for_each = var.redis_maintenance_policy != null ? [1] : []
    
        content {
          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
                }
              }
            }
          }
    

    This way, I was able to dynamically create the maintenance_policy block. If the customer want it, they can provide the variable, if not, then nothing will be provided.

    PS: I only realised now that the default from the variable led to a wrong assumption, this is not mandatory block.


  2. Since only one block is allowed, it seems dynamic cannot be used. Keeping that in mind, the following should work:

     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
                  }
               }
            }
         }
      }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search