terraform-provider-aws: aws_subnet_ids Data source is returning String

This issue was originally opened by @rajivreddy as hashicorp/terraform#22099. It was migrated here as a result of the provider split. The original body of the issue is below.


Terraform Version

➜  private_subnets git:(dev) ✗ terraform -v
Terraform v0.12.2
+ provider.aws v2.14.0

Terraform Configuration Files

data.tf


data "aws_subnet_ids" "public_subnet_ids" {
  vpc_id = var.vpc_id
  tags = merge(
    {
      "Environment" = format("%s", var.environment)
      "Tier"        = var.public_subnet_suffix
    },
    var.additional_tags
  )
}

main.tf


resource "aws_nat_gateway" "nat" {
  count = var.create_nat_in_each_az ? 3 : 1
  allocation_id = element(aws_eip.nat_eip.*.id,count.index)
  subnet_id     =  element(data.aws_subnet_ids.public_subnet_ids,count.index) # this is not working
  tags = merge(
    {
      "Name"        = format("%s-nat-gateway-%s-%d", var.name, var.environment,count.index+1)
      "Environment" = format("%s", var.environment)
    },
    var.additional_tags
  )
  lifecycle {
    create_before_destroy = true
    ignore_changes = [
      tags,
    ]
  }
}

Expected Behavior

aws_nat_gateway modules should be able to get individual public_subnet_ids based on count.index based on https://www.terraform.io/docs/providers/aws/d/subnet_ids.html#example-usage As return value of data.aws_subnet_ids.public_subnet_ids.ids should be a list

Actual Behavior

➜  private_subnets git:(dev) ✗ terraform apply
data.aws_availability_zones.az[0]: Refreshing state...
aws_eip.nat_eip[0]: Refreshing state... [id=eipalloc-sdsd]
data.aws_subnet_ids.public_subnet_ids: Refreshing state...

Error: Error in function call

  on main.tf line 30, in resource "aws_nat_gateway" "nat":
  30:   subnet_id     =  "${element(data.aws_subnet_ids.public_subnet_ids.ids,count.index)}"
    |----------------
    | count.index is 0
    | data.aws_subnet_ids.public_subnet_ids.ids is set of string with 3 elements

Call to function "element" failed: cannot read elements from set of string.

Steps to Reproduce

Please list the full steps required to reproduce the issue, for example: use the example listed https://www.terraform.io/docs/providers/aws/d/subnet_ids.html#example-usage with 0.12.x TF version

  1. terraform init
  2. terraform plan
  3. terraform apply

References

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 6
  • Comments: 16 (2 by maintainers)

Most upvoted comments

Convert it to a list should work

data “aws_subnet_ids” “private” { vpc_id = “${var.vpc_id}”

tags = { Tier = “Private” } }

resource “aws_instance” “app” { count = “3” ami = “${var.ami}” instance_type = “t2.micro” subnet_id = “${element(tolist(data.aws_subnet_ids.private.ids), count.index)}” }

Someone really needs to update the docs to say that then.

“aws_subnet_ids provides a list of ids for a vpc_id”

As @ninjapugdevil and @rajivreddy mentioned, using the tolist function will work. This is because the aws_subnet_ids data source returns a set and not a list.

See:

The new aws_subnets data source returns ids as a list.

As @ninjapugdevil and @rajivreddy mentioned, using the tolist function will work. This is because the aws_subnet_ids data source returns a set and not a list.

See:

I used something like this :

# define a data provider
data "aws_subnet" "subnet-prv-1" {
  count = "${length(data.aws_subnet_ids.prv-1.ids)}"
  id    = "${tolist(data.aws_subnet_ids.prv-1.ids)[count.index]}"
}
 
# use them in this way
subnets         = ["${data.aws_subnet.subnet-prv-1[0].id}"]