How to produce a map from the cartesian product of two lists to use with for_each on a resource with Terraform I need to create a datadog synthetics monitors with the resource datadog_synthetics_test
I need to monitor multiples cluster, with multiple point of view :
# Clusters
variable &quot;datadog_gke_clusters&quot; {
  default = [
    # NPRD
    {
      name        = &quot;cluster01&quot;
      environment = &quot;nprd&quot;
      url = {
        private = &quot;https://private.domain-priv.com&quot;
        public  = &quot;https://public.domain.com&quot;
      }
    },
    # PROD
    {
      name        = &quot;cluster02&quot;
      environment = &quot;nprd&quot;
      url = {
        private = &quot;https://private.domain-priv.com&quot;
        public  = &quot;https://public.domain.com&quot;
      }
    }
  ]
}

# Point of views
variable &quot;gke_slo&quot; {
  description = &quot;Response time threshold in ms to respond to a request.&quot;
  default = [
    {
      zone              = private
      monitor_threshold = 50
    },
    {
      zone              = public
      monitor_threshold = 100
    },
  ]
}

for_each need a map or a list of strings
resource &quot;datadog_synthetics_test&quot; &quot;gke-monitoring&quot; {
  for_each = ... # cartesian product of lists

  type    = &quot;api&quot;
  subtype = &quot;http&quot;
  ....
}

There is a function [setproduct(sets...)][1] which produce a list which combine values of each list, but not a map.
I would need to produce a map which look like this :
  {
    &quot;cluster01-private&quot; = {
      name        = &quot;cluster01&quot;
      environment = &quot;nprd&quot;
      url = {
        private = &quot;https://private.cluster01.domain-priv.com&quot;
        public  = &quot;https://public.cluster01.domain.com&quot;
      }
      zone              = private
      monitor_threshold = 50
    },
    &quot;cluster01-public&quot; = {
      name        = &quot;cluster01&quot;
      environment = &quot;nprd&quot;
      url = {
        private = &quot;https://private.cluster01.domain-priv.com&quot;
        public  = &quot;https://public.cluster01.domain.com&quot;
      }
      zone              = public
      monitor_threshold = 100
    },
    # PROD
    .... etc
  }

How could I do that ?
In 2 steps, you can first create your cartesian product in a variable:
locals {
  datadog_gke_clusters_by_pov = flatten([
    for cluster in var.datadog_gke_clusters : [
      for pov in var.gke_slo_ : {
        cluster    = cluster
        pov        = pov
      }
    ]
  ])
}

And then use this new variable in your resource block:
resource &quot;datadog_synthetics_test&quot; &quot;gke-monitoring&quot; {
  for_each = {
    for valuue in local.datadog_gke_clusters_by_pov : &quot;${valuue.cluster.name}-${valuue.pov.zone_name}&quot; =&gt; valuue
  }
...
# here you can use each.value.cluster.* and each.value.pov.*
}

Have a good day!