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 = aws_vpc.main.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

Hi @apparentlymart ,

Hope you are doing well. I got the same question and would like to answer some of your mentioned question for better understanding.

I got;
3 public subnet
9 private subnet
Now, I would like to deploy 3 NAT gateway in public subnet and associate with EIP but whne I tried I have got an SUBENT_ID error.

Error: creating EC2 NAT Gateway: InvalidSubnet: The subnet ID ‘us-east-1b’ is malformed
│ status code: 400, request id: 3858caad-d9fc-4fc4-b4de-6d6d3268e7af

.tf file:

resource "aws_nat_gateway" "ngw" {
  count = length(var.pub_web_sub_cidr)

  allocation_id     = aws_eip.eip_nat1[count.index].id
  connectivity_type = "public"
  subnet_id         = var.pub_web_availablity_zone[count.index]
}