Cartesian product issue

Hello everyone,
I’m trying to create a dynamic list created by the Cartesian product of 2 lists - you can call it nested for loop.

If you will run a plan with the attached code, the lists - “queues_names” and “expected_queues_names” look the same but the data structure I’m trying to create with them is different.
I’m expecting to create the - “expected_block” (list of maps) but the data structure “block” is created differently.

Can someone explain to me why it seems that I’m using the same lists but the results are totally different?

locals {
  vendors               = ["AA", "BB", "CC"]
  queues-topic          = ["tasks", "completed", "stopped"]

  queues_names          = [
  for queue in local.queues-topic :
    [
      for vendor in local.vendors : [
        "${queue}-${vendor}"
      ]
    ]
  ]
  expected_queues_names = [
    "tasks-AA",
    "tasks-BB",
    "tasks-CC",
    "completed-AA",
    "completed-BB",
    "completed-CC",
    "stopped-AA",
    "stopped-BB",
    "stopped-CC",
  ]

  block = [
  for x in local.queues_names :
    {
      name = "${x}"
    }
  ]
  expected_block = [
  for x in local.expected_queues_names :
    {
      name = "${x}"
    }
  ]
}

output queues_names {
  value = flatten(local.queues_names)
}

output block {
  value = flatten(local.block)
}

output expected_queues_names {
  value = flatten(local.expected_queues_names)
}

output expected_block {
  value = flatten(local.expected_block)
}

You can use “flatten” as part of the queues_names to flatten the output. You are flattening it in the print, so you are not seeing the issue in the output.

queues_names = flatten([
for queue in local.queues-topic :

])

1 Like

Worked for me, thank you!

It might also be interesting to know that the process you’re trying to implement here has a built-in function setproduct which can achieve the same result with only one level of for expression:

locals {
  vendors               = ["AA", "BB", "CC"]
  queues-topic          = ["tasks", "completed", "stopped"]

  queues_names = [
    for pair in setproduct(local.queues-topic, local.vendors) :
    join("-", pair)
  ]
}

The setproduct function alone will produce a collection of pair tuples like ["tasks", "AA"] and so the for expression is there just to apply the join function to them in order to get the dash-delimited strings you showed in your example.

1 Like