Invalid function argument for setproduct

I have a similar need and facing this issue.
./modules/target_group.tf

resource aws_lb_target_group "this" {
  for_each = var.target_group
  name     = each.value.name
  port     = each.value.port
  protocol = var.tg_protocol
  vpc_id   = var.vpc_id
  health_check {
    path                = each.value.health_check_path
    enabled             = true
    interval            = each.value.health_check_interval
    port                = "traffic-port"
  }
}

resource "aws_lb_target_group_attachment" "this" {
  for_each = {
  for pair in setproduct(keys(aws_lb_target_group.this), data.aws_instances.this) :
  "${pair[0]}:${pair[1]}" => {
    target_group_arn = aws_lb_target_group.this[pair[0]]
    target_id  = pair[1]
  }
  }
  target_group_arn = each.value.target_group_arn
  target_id        = each.value.target_id
  port             = 80
}

./modules/data/tf

data aws_instances "this" {
  for_each = var.target_group
  filter {
    name   = "tag:Name"
    values = each.value.instance_filter
  }
}

./locals.tf

locals {

  dna_target_groups = {
    protocol        = "HTTP"
    attachment_port = 80
    groups = {
      myenergy = {
        name                       = "myenergy-${var.zone}"
        port                       = 8080
        instance_filter            = ["tableau-node-1*", "tableau-node-2*"]
        listener_rule_path_pattern = ["/projection/*", "/myenergy-core/*", "/customer-behaviour/*"]
        listener_rule_priority     = 1
      },
      haproxy = {
        name                       = "haproxy-${var.zone}"
        port                       = 8080
        instance_filter            = ["tableau-node-2*"]
        attachment_port            = 80
        listener_rule_path_pattern = ["foobar.com", "google.co.uk"]
        listener_rule_priority     = 2
      },
      opencust = {
        name              = "opencust-${var.zone}"
        port              = 8080
        health_check_path = "/jmx-console/"
        instance_filter = [
          "tableau-node-2*",
        "tableau-node-3*"]
        attachment_port            = 80
        listener_rule_path_pattern = ["msn.com", "bbc.co.uk"]
        listener_rule_priority     = 3
      }
    }
  }

}

The error this gives is

Error: Invalid function argument

  on modules/target_group/target_group.tf line 29, in resource "aws_lb_target_group_attachment" "this":
  29:   for pair in setproduct(keys(aws_lb_target_group.this), data.aws_instances.this) :
    |----------------
    | data.aws_instances.this is object with 3 attributes

Invalid value for "sets" parameter: a set or a list is required.

Hi @nmarchini,

What you described seems a little different to what was being discussed in the topic you originally posted it in, so I’ve split it into a separate topic.

The error message you shared contains two pieces of information that together explain what caused the error:

  • “data.aws_instances.this is object with 3 attributes”
  • “a set or a list is required”

This failed because you passed an object (data.aws_instances.this) to a function that accepts only sets or lists.

If your goal was to use the keys from var.target_group (which are also the keys of data.aws_instances.this) as the second value in each of your pairs, you can use the keys function in the same way as you did for the first argument:

for pair in setproduct(
  keys(aws_lb_target_group.this),
  keys(data.aws_instances.this),
) :
...

The keys function returns a list of keys from the map or object in lexical order, so that should then be compatible with the expectations of the setproduct function.