Validation for Optional and List of Objects Variables

I am struggling to get a validation step for a list of objects. In addition, I need the list to be optional and check for a value before running the validation. Below is the example for monitor autoscale setting resource.

variable "default_scaling_profile" {
  type = object({
    capacity     = number
    min_capacity = optional(number)
    max_capacity = optional(number)
    trigger = optional(list(object({
      metric_name          = string
      operator             = string
      threshold            = number
      scale_action         = string
      scale_instance_count = number
      time_window          = number
      scale_cooldown       = number
    })), [])
  })
  default = {
    capacity     = 1
    min_capacity = 1
    max_capacity = 3
    trigger = [
      {
        metric_name          = "Percentage CPU"
        operator             = "GreaterThan"
        threshold            = 60
        scale_action         = "Increase"
        scale_instance_count = 1
        time_window          = 5
        scale_cooldown       = 5
      },
      {
        metric_name          = "Percentage CPU"
        operator             = "LessThan"
        threshold            = 20
        scale_action         = "Decrease"
        scale_instance_count = 1
        time_window          = 5
        scale_cooldown       = 5
      }
    ]
  }
  validation {
    condition = ! contains([
      for profile in var.default_scaling_profile :
          [for trigger in profile.trigger : 
            profile.trigger != [] ?
              contains(["GreaterThan", "LessThan", "GreaterThanOrEqual", "NotEquals", "Equals", "LessThanOrEqual"], trigger.operator)
          : true]   
    ], false)
    error_message = "Threshold operator must be one of following values: GreaterThan, LessThan,GreaterThanOrEqual, NotEquals, Equals, LessThanOrEqual."
  }
  validation {
    condition = ! contains([
      for profile in var.default_scaling_profile : 
          [for trigger in profile.trigger : 
            profile.trigger != [] ?
              contains(["Increase", "Decrease"], trigger.scale_action)
          : true] 
    ], false)
    error_message = "Scale action must be one of the following: Increase or Decrease."
  }
}

Below is the resulting error:

│ Error: Unsupported attribute
│
│   on ..\..\variables.tf line 70, in variable "default_scaling_profile":
│   70:           [for trigger in profile.trigger :
│
│ Can't access attributes on a primitive-typed value (number).
╵
╷
│ Error: Attempt to get attribute from null value
│
│   on ..\..\variables.tf line 70, in variable "default_scaling_profile":
│   70:           [for trigger in profile.trigger :
│
│ This value is null, so it does not have any attributes.
╵
╷
│ Error: Unsupported attribute
│
│   on ..\..\variables.tf line 70, in variable "default_scaling_profile":
│   70:           [for trigger in profile.trigger :
│
│ 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?
╵
╷
│ Error: Unsupported attribute
│
│   on ..\..\variables.tf line 80, in variable "default_scaling_profile":
│   80:           [for trigger in profile.trigger :
│
│ Can't access attributes on a primitive-typed value (number).
╵
╷
│ Error: Attempt to get attribute from null value
│
│   on ..\..\variables.tf line 80, in variable "default_scaling_profile":
│   80:           [for trigger in profile.trigger :
│
│ This value is null, so it does not have any attributes.
╵
╷
│ Error: Unsupported attribute
│
│   on ..\..\variables.tf line 80, in variable "default_scaling_profile":
│   80:           [for trigger in profile.trigger :
│
│ 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?
╵

Any assistance in how I can structure the validation step to allow access to a list of objects and check for the existence of a value would be greatly appreciated.

I haven’t checked your entire condition to make sure this is the only error, but the first problem is here:

for profile in var.default_scaling_profile

You’re using a for expression on var.default_scaling_profile, but it’s an object, not a list of objects. I don’t think this expression should exist at all, and you should instead write e.g.

for trigger in var.default_scaling_profile.trigger

For your use of contains and !contains with a list of boolean values, you may want to use the alltrue and anytrue functions, but that’s just for clarity.

Thank you. That solved the issue for me. I have another profile variable that is a list(object()) and I got tunnel vissioned on that. Thanks again.