How to get `subnet_id` for `aws_nat_gateway` from dynamically created `aws_subnet`

I have created an aws-subnet dynamically

resource "aws_subnet" "public" {
  for_each = var.public_cidrs
  vpc_id =
  availability_zone = each.key
  cidr_block = each.value
   map_public_ip_on_launch = true
  tags = merge(var.tags, {
    Name = join("-", [var.tags["Env"], var.tags["Project"],"public-subnet", each.key])

Now I would like to create an aws_nat_gateway like following

resource "aws_nat_gateway" "nat-gateway" {
    subnet_id = "<subnet_id>"

Here I need a subnet_id from aws_subnet created previously.
How can I get that?

Hi @anjanpaul,

In your example you have declared an arbitrary number of subnets based on the number of elements in an input variable.

You now need to make a similar decision about the NAT gateway resource: do you want a separate NAT gateway per subnet? Do you want only one NAT gateway in only one of your subnets, and if so what is the rule for deciding which one?

Based on the answers to these questions you can use expressions to explain your intentions to Terraform, but exactly what you would write depends on the goal.

If you aren’t sure, it can help to write out what this configuration would look like if you were manually declaring each subnet and NAT gateway separately (not using for_each) and share that here so we can consider different ways to generalize it into systematic rules based on the variable afterwards.

You could do the following:

subnet_id =    aws_subnet.public[element(keys(aws_subnet.public), 0)].id

Changing 0 would change the subnet index.

1 Like

@marciogmorales Thanks it worked for me
but my question is I don’t understand why element(aws_subnet.public_subnet.*.id, 0) won’t work, I tried but always got an error

This object does not have an attribute named id   subnet_id = element(aws_subnet.public.*.id, 0)

please help me understand
note: I used for_each not count for creating subnets and other resources