How do you put multiple subnet cidrs into a securitygroup cidr_block from a data lookup

I need help figuring out how to loop through and put each subnet cidr into the cidr_blocks part of an ingress rule for a security group. I know there are 5 subnets and thus 5 cidrs that I should be adding here but I cant figure out the for_each way of doing this. Can someone point me in the right direction please? I cant seem to find a current good example to shed any light on this. Thanks!

data "aws_subnet" "cidr" { #Yes, poorly named but this is what I was given to fix.
  for_each = toset(data.aws_subnets.public.ids)
  id       = each.value
}

data "aws_subnets" "public" {
  filter {
    name   = "vpc-id"
    values = [var.vpc_id]
  }

  filter {
    name   = "tag:Name"
    values = ["${var.environment}-public-*"]
  }

  tags = {
    Type = "Public"
  }
}

resource "aws_security_group" "security_group" {
  name        = var.instance_role
  description = "${var.instance_role} ${var.environment}"
  vpc_id      = var.vpc_id
  lifecycle {
    create_before_destroy = true
  }

  ingress {
    description = ""
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = [data.aws_subnet.cidr.*.cidr_block]
  }
}

Hi @seth.floyd,

I think you’re on the right track but you’re using the .* operator, which is intended for lists, with a map value. That means the result isn’t what you’re intending.

Here’s one way to write that cidr_blocks expression to get the result I think you want:

    cidr_blocks = [ for subnet in data.aws_subnet.cidr : subnet.cidr_block ]

Alternatively, you can make the .* and [*] operators work by applying them to the result of the values function, which produces a list of the values from a map while discarding the keys:

    cidr_blocks = values(data.aws_subnet.cidr)[*].cidr_block

I used [*] instead of .* because it’s the more modern operator, although in this particular case it doesn’t actually matter and both would behave the same.

I tend to prefer the first approach I wrote, using a for expression, because I tend to think it’s easier to read for a future maintainer. However, the second approach is also relatively common among those who choose to prioritize brevity. They should both achieve the same result.

Appreciate it…that got me going in the right direction. :+1: