For_each with list/map of objects and defaults

Hi folks

I’m trying to achieve something that clearly isn’t fully supported by current versions of Terraform, but is probably quite a common use case.

I have a list of objects (which could easily be a map):

terraform.tfvars

node_groups = [
    {
        name = "app1"
        instance_types = ["t3a.xlarge"]
    },
    {
        name = "app2"
        scaling = {
            max = 2
        }
    },
    {
        name = "api"
        instance_types = ["m5a.4xlarge"]
        disk_size      = 50
    },
    {
        name = "db"
        instance_types = ["i3.8xlarge"]
        disk_size      = 50
        scaling = {
            min     = 2
            max     = 5
            desired = 2
        }
    }
]

I’m using Terraform 1.3.0-beta1 with some optional defaults:

variables.tf

variable "node_groups" {
  type = list(object({
    name           = string
    instance_types = optional(list(string), ["t3.medium"])
    disk_size      = optional(number, 20)
    scaling = optional(object({
      min     = optional(number, 1)
      max     = optional(number, 3)
      desired = optional(number, 1)
      }), {
      min     = 1
      max     = 3
      desired = 1
    })
    max_unavailable = optional(number, 1)
  }))

main.tf

for_each = var.node_groups

disk_size      = each.value.disk_size
instance_types = each.value.instance_types

config_scaling = [{
    min_size     = each.value.scaling.min
    max_size     = each.value.scaling.max
    desired_size = each.value.scaling.desired
}]

Hopefully this is enough code to see what I’m trying to do - most of my node groups share common attributes, and I want to use these defaults along with some changes. I know I can do this if I populate each attribute on each object, but I’d rather not use that repetition of data because the list of different node groups will continue to grow over time.

I’ve tried a few different approaches incl for_each = { for k, v in var.node_groups : k => v } and some flatten work, but I can’t seem to find the right approach.

Can anyone point me in the right direction?

Hi @duncanwraight!

I’m afraid I’m not really sure exactly what the problem you’ve encountered, but the first thing that sticks out to me from your examples is that you’ve assigned var.node_groups directly to for_each, which is invalid because for_each requires a map.

You mentioned that the list of objects “could easily be a map” though, and I’m not sure what you mean by that. I would expect that changing it to be a map of objects would be sufficient to make this work, but I suspect I’m missing something.