Home > database >  How to combine aws_subnet.prod_subnet.*.id with aws_subnet.prod2_subnet.*.id into a single list
How to combine aws_subnet.prod_subnet.*.id with aws_subnet.prod2_subnet.*.id into a single list

Time:01-11

I am trying to combine all subnets to be able to attach an ACL to them.

I have two subnets that exist which different resource names, so it's forcing me to have two ACL blocks which I don't want.

Right now the ACL subnet_id blocks for both ACL blocks read as:

resource "aws_network_acl" "prod_public" {
  vpc_id = aws_vpc.prod.id
  subnet_ids = aws_subnet.prod_public.*.id
}

resource "aws_network_acl" "prod2_public" {
  vpc_id = aws_vpc.prod.id
  subnet_ids = aws_subnet.prod2_public.*.id
}

this works, but I'm want something that will create a list of BOTH set of subnet_ids so I can just have be one block.

I've tried something like this, but didn't work.

resource "aws_network_acl" "prods_public" {
  vpc_id = aws_vpc_prod_id
  subnet_ids = [aws_subnet.prod_public.*.id, aws_subnet.prod2_public.*.id]
}

I also tried using tostring and toset which didn't work either.

CodePudding user response:

You should use concat:

subnet_ids = concat(aws_subnet.prod_public.*.id, aws_subnet.prod2_public.*.id)

CodePudding user response:

Because neither of these resources is using the count argument, the splat operator * is redundant here and it would be sufficient to just refer to the single object for each resource:

resource "aws_network_acl" "prods_public" {
  vpc_id = aws_vpc_prod_id
  subnet_ids = [
    aws_subnet.prod_public.id,
    aws_subnet.prod2_public.id,
  ]
}

Using the legacy splat operator .* (or its modern equivalent [*]) makes Terraform convert each single object into a one-element list containing that object, and so in your example you created a list of lists of strings rather than just a list of strings.

If you were using count for these resources then their values would then actually be lists, and so in that case it would be appropriate to use the splat operator to select just the id attribute of each one but you'd then need to use a function to combine the multiple lists together. Because subnet_ids expects a set of subnet ID strings (the subnets have no meaningful order), the clearest way to represent that would be using the setunion function, which will produce a set of strings containing all of the distinct elements across all of the given lists:

resource "aws_network_acl" "prods_public" {
  vpc_id = aws_vpc_prod_id
  subnet_ids = setunion(
    aws_subnet.prod_public[*].id,
    aws_subnet.prod2_public[*].id,
  )
}

Using the concat function would also work, but ultimately Terraform will convert its result into a set of strings to pass into subnet_ids anyway and so using concat might be misleading to a future reader who might assume that means that the ordering of the subnet IDs is somehow significant.

  • Related