terraform-aws-modules/terraform-aws-vpc

Error when creating VPC without any private subnets and has NAT gateways

aiell0 opened this issue · 8 comments

Description

When creating a VPC with only public subnets and with one_nat_gateway_per_az configured, module fails with an error.

Versions

  • Module version [Required]: 5.7.1

  • Terraform version: 1.7.5

  • Provider version(s): 5.45.0

Reproduction Code [Required]

module "outbound_vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~>5.0"

  name = "outbound"
  cidr = "192.168.16.0/21"

  azs            = ["us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d", "us-east-1e", "us-east-1f"]
  public_subnets = ["192.168.16.0/23", "192.168.18.0/23", "192.168.20.0/24", "192.168.21.0/24", "192.168.22.0/24", "192.168.23.0/24"]

  enable_nat_gateway     = true
  single_nat_gateway     = false
  one_nat_gateway_per_az = true
}

Steps to reproduce the behavior:

Run a terraform plan or terraform apply.

Expected behavior

VPC creates without issues.

Actual behavior

Module errors out.

Terminal Output Screenshot(s)

│ Error: Error in function call
│ 
│   on .terraform/modules/outbound_vpc/main.tf line 1088, in resource "aws_route" "private_nat_gateway":
│ 1088:   route_table_id         = element(aws_route_table.private[*].id, count.index)
│     ├────────────────
│     │ while calling element(list, index)
│     │ aws_route_table.private is empty tuple
│     │ count.index is 0
│ 
│ Call to function "element" failed: cannot use element function with an empty list.

Additional context

This use case comes from AWS Prescriptive Guidance around setting up network architecture. In this case, an outbound VPC would only have NAT gateways. This VPC would then have routes to it via Transit Gateway connections to other VPCs which emulates the same functionality as private subnets. This module does not support that setup in the current form.

From my understanding you have to define private subnets in the egress vpc cf here ...

@laserpedro not quite....the egress VPC can live in another account and has just public subnets with NAT gateways living in them. You can then use a Transit Gateway to link those subnets with private subnets in separate VPCs that live in separate accounts. By creating a VPC with just public subnets for the egress VPC, you can keep the IP space small (which is desirable because this will be an internet-facing VPC after all).

What about using non routable IPs for the private subnets in your egress VPC ?

This issue has been automatically marked as stale because it has been open 30 days
with no activity. Remove stale label or comment or this issue will be closed in 10 days

I really think this is a valid use case and it's something I already witnessed on a past project. Also, AWS documents this pattern on some architectures, like here. I also made some local changes to the module so that the reproduction code (shared by @aiell0) works as expected. Can I open a PR for this? :)

This issue has been automatically marked as stale because it has been open 30 days
with no activity. Remove stale label or comment or this issue will be closed in 10 days

This issue was automatically closed because of stale in 10 days

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.