terraform-aws-modules / terraform-aws-vpc

Terraform module to create AWS VPC resources πŸ‡ΊπŸ‡¦
https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws
Apache License 2.0
2.98k stars 4.44k forks source link

Adding additional VPC into account breaking with: Call to function "element" failed: cannot use element function with an empty list. #734

Open nodesocket opened 2 years ago

nodesocket commented 2 years ago

Description

Hello. I had a previous VPC defined using:

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "3.2.0"

  name = "vpc-stage"
  cidr = "192.168.0.0/18"

  azs = data.aws_availability_zones.usw2.names

  public_subnets = [
    "192.168.0.0/20",
    "192.168.16.0/20",
    "192.168.32.0/20",
  ]

  enable_nat_gateway   = true
  enable_vpn_gateway   = false
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Terraform   = "true"
    Environment = "stage"
  }

  public_subnet_tags = {
    "kubernetes.io/cluster/acme-org-stage" = "owned"
  }
}

Trying to create a new VPC alongside the existing VPC using the following:

module "vpc_nat" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "3.2.0"

  name = "vpc-nat-stage"
  cidr = "10.0.0.0/16"

  azs = data.aws_availability_zones.usw2.names

  private_subnets = [
    "10.0.0.0/20",
    "10.0.16.0/20",
    "10.0.32.0/20"
  ]

  public_subnets = [
    "10.0.48.0/20",
    "10.0.64.0/20",
    "10.0.80.0/20"
  ]

  enable_nat_gateway     = true
  single_nat_gateway     = false
  one_nat_gateway_per_az = true
  enable_vpn_gateway     = false
  enable_dns_support     = true
  enable_dns_hostnames   = true
  reuse_nat_ips          = true
  external_nat_ip_ids    = aws_eip.nat.*.id

  private_subnet_tags = {
    Private                                                = true
    "kubernetes.io/cluster/acme-org-stage" = "owned"
  }

  public_subnet_tags = {
    Private = false
  }

  tags = {
    Terraform   = "true"
    Environment = "stage"
  }
}

But it is erroring inside of the this module with:

β”‚ Error: Error in function call
β”‚
β”‚   on .terraform/modules/vpc_nat/main.tf line 1090, in resource "aws_nat_gateway" "this":
β”‚ 1090:   subnet_id = element(
β”‚ 1091:     aws_subnet.public.*.id,
β”‚ 1092:     var.single_nat_gateway ? 0 : count.index,
β”‚ 1093:   )
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ aws_subnet.public is empty tuple
β”‚     β”‚ count.index is 0
β”‚     β”‚ var.single_nat_gateway is false
β”‚
β”‚ Call to function "element" failed: cannot use element function with an empty list.
β•΅
β•·
β”‚ Error: Error in function call
β”‚
β”‚   on .terraform/modules/vpc_nat/main.tf line 1090, in resource "aws_nat_gateway" "this":
β”‚ 1090:   subnet_id = element(
β”‚ 1091:     aws_subnet.public.*.id,
β”‚ 1092:     var.single_nat_gateway ? 0 : count.index,
β”‚ 1093:   )
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ aws_subnet.public is empty tuple
β”‚     β”‚ count.index is 1
β”‚     β”‚ var.single_nat_gateway is false
β”‚
β”‚ Call to function "element" failed: cannot use element function with an empty list.
β•΅
β•·
β”‚ Error: Error in function call
β”‚
β”‚   on .terraform/modules/vpc_nat/main.tf line 1090, in resource "aws_nat_gateway" "this":
β”‚ 1090:   subnet_id = element(
β”‚ 1091:     aws_subnet.public.*.id,
β”‚ 1092:     var.single_nat_gateway ? 0 : count.index,
β”‚ 1093:   )
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ aws_subnet.public is empty tuple
β”‚     β”‚ count.index is 2
β”‚     β”‚ var.single_nat_gateway is false
β”‚
β”‚ Call to function "element" failed: cannot use element function with an empty list.
β•΅
β•·
β”‚ Error: Error in function call
β”‚
β”‚   on .terraform/modules/vpc_nat/main.tf line 1090, in resource "aws_nat_gateway" "this":
β”‚ 1090:   subnet_id = element(
β”‚ 1091:     aws_subnet.public.*.id,
β”‚ 1092:     var.single_nat_gateway ? 0 : count.index,
β”‚ 1093:   )
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ aws_subnet.public is empty tuple
β”‚     β”‚ count.index is 3
β”‚     β”‚ var.single_nat_gateway is false
β”‚
β”‚ Call to function "element" failed: cannot use element function with an empty list.
β•΅
β•·
β”‚ Error: Error in function call
β”‚
β”‚   on .terraform/modules/vpc_nat/main.tf line 1207, in resource "aws_route_table_association" "public":
β”‚ 1207:   subnet_id      = element(aws_subnet.public.*.id, count.index)
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ aws_subnet.public is empty tuple
β”‚     β”‚ count.index is 0
β”‚
β”‚ Call to function "element" failed: cannot use element function with an empty list.
β•΅
β•·
β”‚ Error: Error in function call
β”‚
β”‚   on .terraform/modules/vpc_nat/main.tf line 1207, in resource "aws_route_table_association" "public":
β”‚ 1207:   subnet_id      = element(aws_subnet.public.*.id, count.index)
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ aws_subnet.public is empty tuple
β”‚     β”‚ count.index is 2
β”‚
β”‚ Call to function "element" failed: cannot use element function with an empty list.
β•΅
β•·
β”‚ Error: Error in function call
β”‚
β”‚   on .terraform/modules/vpc_nat/main.tf line 1207, in resource "aws_route_table_association" "public":
β”‚ 1207:   subnet_id      = element(aws_subnet.public.*.id, count.index)
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ aws_subnet.public is empty tuple
β”‚     β”‚ count.index is 1
β”‚
β”‚ Call to function "element" failed: cannot use element function with an empty list.

Versions

+ provider registry.terraform.io/hashicorp/aws v3.48.0
+ provider registry.terraform.io/hashicorp/cloudinit v2.2.0
+ provider registry.terraform.io/hashicorp/kubernetes v1.13.4
+ provider registry.terraform.io/hashicorp/local v2.1.0
+ provider registry.terraform.io/hashicorp/random v3.1.0
+ provider registry.terraform.io/terraform-aws-modules/http v2.4.1

Reproduction

Steps to reproduce the behavior: Not using workspaces. I tried rm -rf .terraform && terraform init && terraform plan but the error is consistent.

Code Snippet to Reproduce

terraform plan
antonbabenko commented 2 years ago

Could you also include terraform plan output for the failed apply?

nodesocket commented 2 years ago

@antonbabenko thanks for the reply. Sure, the terraform plan is below. I also included it above though. Looks like the root problem is:

aws_subnet.public is empty tuple
|
β”‚ Error: Error in function call
β”‚
β”‚   on .terraform/modules/vpc_nat/main.tf line 1090, in resource "aws_nat_gateway" "this":
β”‚ 1090:   subnet_id = element(
β”‚ 1091:     aws_subnet.public.*.id,
β”‚ 1092:     var.single_nat_gateway ? 0 : count.index,
β”‚ 1093:   )
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ aws_subnet.public is empty tuple
β”‚     β”‚ count.index is 1
β”‚     β”‚ var.single_nat_gateway is false
β”‚
β”‚ Call to function "element" failed: cannot use element function with an empty list.
β•΅
β•·
β”‚ Error: Error in function call
β”‚
β”‚   on .terraform/modules/vpc_nat/main.tf line 1090, in resource "aws_nat_gateway" "this":
β”‚ 1090:   subnet_id = element(
β”‚ 1091:     aws_subnet.public.*.id,
β”‚ 1092:     var.single_nat_gateway ? 0 : count.index,
β”‚ 1093:   )
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ aws_subnet.public is empty tuple
β”‚     β”‚ count.index is 2
β”‚     β”‚ var.single_nat_gateway is false
β”‚
β”‚ Call to function "element" failed: cannot use element function with an empty list.
β•΅
β•·
β”‚ Error: Error in function call
β”‚
β”‚   on .terraform/modules/vpc_nat/main.tf line 1090, in resource "aws_nat_gateway" "this":
β”‚ 1090:   subnet_id = element(
β”‚ 1091:     aws_subnet.public.*.id,
β”‚ 1092:     var.single_nat_gateway ? 0 : count.index,
β”‚ 1093:   )
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ aws_subnet.public is empty tuple
β”‚     β”‚ count.index is 3
β”‚     β”‚ var.single_nat_gateway is false
β”‚
β”‚ Call to function "element" failed: cannot use element function with an empty list.
β•΅
β•·
β”‚ Error: Error in function call
β”‚
β”‚   on .terraform/modules/vpc_nat/main.tf line 1090, in resource "aws_nat_gateway" "this":
β”‚ 1090:   subnet_id = element(
β”‚ 1091:     aws_subnet.public.*.id,
β”‚ 1092:     var.single_nat_gateway ? 0 : count.index,
β”‚ 1093:   )
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ aws_subnet.public is empty tuple
β”‚     β”‚ count.index is 0
β”‚     β”‚ var.single_nat_gateway is false
β”‚
β”‚ Call to function "element" failed: cannot use element function with an empty list.
β•΅
β•·
β”‚ Error: Error in function call
β”‚
β”‚   on .terraform/modules/vpc_nat/main.tf line 1207, in resource "aws_route_table_association" "public":
β”‚ 1207:   subnet_id      = element(aws_subnet.public.*.id, count.index)
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ aws_subnet.public is empty tuple
β”‚     β”‚ count.index is 2
β”‚
β”‚ Call to function "element" failed: cannot use element function with an empty list.
β•΅
β•·
β”‚ Error: Error in function call
β”‚
β”‚   on .terraform/modules/vpc_nat/main.tf line 1207, in resource "aws_route_table_association" "public":
β”‚ 1207:   subnet_id      = element(aws_subnet.public.*.id, count.index)
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ aws_subnet.public is empty tuple
β”‚     β”‚ count.index is 0
β”‚
β”‚ Call to function "element" failed: cannot use element function with an empty list.
β•΅
β•·
β”‚ Error: Error in function call
β”‚
β”‚   on .terraform/modules/vpc_nat/main.tf line 1207, in resource "aws_route_table_association" "public":
β”‚ 1207:   subnet_id      = element(aws_subnet.public.*.id, count.index)
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ aws_subnet.public is empty tuple
β”‚     β”‚ count.index is 1
β”‚
β”‚ Call to function "element" failed: cannot use element function with an empty list.
nodesocket commented 2 years ago

@antonbabenko do you need anything else? Is creating multiple VPCs in the same terraform project supported? This seems like a potential bug.

antonbabenko commented 2 years ago

Yes, this looks like a bug related to incorrect tracking of one_nat_gateway_per_az = true. Creating multiple VPCs in the same project is supported.

pawelpesz commented 2 years ago

Any news on this? At the moment the only working configuration when creating multiple VPCs in the same project seems to be the default one:

enable_nat_gateway     = true
single_nat_gateway     = false
one_nat_gateway_per_az = false
pawelpesz commented 2 years ago

Please disregard my previous comment, the error in question springs up only when the subnet list is empty.

cuyk commented 2 years ago

It fails not because of a new VPC being added. You provided more availability zones then public subnets. Seems like this count has some logic to prevent you from doing that.

https://github.com/terraform-aws-modules/terraform-aws-vpc#one-nat-gateway-per-availability-zone

The number of public subnet CIDR blocks specified in public_subnets must be greater than or equal to the number of availability zones specified in var.azs. This is to ensure that each NAT Gateway has a dedicated public subnet to deploy to.

snowsky commented 1 year ago

may need to assign private_subnets as well

170031284 commented 7 months ago

Any news on this? At the moment the only working configuration when creating multiple VPCs in the same project seems to be the default one:

enable_nat_gateway     = true
single_nat_gateway     = false
one_nat_gateway_per_az = false

Hey did you get a fix ? Even i have faced a similar error . I am trying to create two vpcs . Two public subnets within the VPC. Two private subnets within the VPC. But both of them are in same ec2 instance . I got the issue with subnets in private vpc .

suminhong commented 7 months ago

This problem occurs because one_nat_gateway_per_az = true, but the number of public subnets is shorter than the azs length. One of the conditions for creating a public subnet

(!var.one_nat_gateway_per_az || local.len_public_subnets >= length(var.azs))

Because it is false, the public subnet is not created, and other errors occur because of this.

Since the value of data.aws_availability_zones.usw2 is 4, but the number of public subnets is 3,

  1. Set one_nat_gateway_per_az = false, or,
  2. Set the number of public subnets to 4 or more.

This can be solved in one of two ways above.