Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
nodesocket opened this issue Jan 20, 2022 · 10 comments
Milestone

Comments

@nodesocket
Copy link

nodesocket commented Jan 20, 2022

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

  • Terraform: v1.0.4
  • Provider(s):
+ 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
  • AWS VPC Module: 3.2.0

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
Copy link
Member

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

@nodesocket
Copy link
Author

nodesocket commented Jan 22, 2022

@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
Copy link
Author

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

@antonbabenko
Copy link
Member

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
Copy link

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
Copy link

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

@cuyk
Copy link

cuyk commented Aug 19, 2022

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
Copy link

snowsky commented Jul 7, 2023

may need to assign private_subnets as well

@bryantbiggs bryantbiggs added this to the v6.0 milestone Nov 21, 2023
@170031284
Copy link

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
Copy link

suminhong commented Apr 13, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants