Terraform: Unable to use output variable as list

Created on 8 Aug 2016  ยท  14Comments  ยท  Source: hashicorp/terraform

Terraform Version

Terraform v0.7.0

Affected Resource(s)

  • aws_elb
  • aws_db_subnet_group

    Terraform Configuration Files

_main.tf_

module "subnets" {
  source = "./modules/test"
}

resource "aws_elb" "elb" {
  name = "test"
  subnets = ["${module.subnets.subnets["public"]}"]
  listener {
    lb_port = 80
    lb_protocol = "http"
    instance_port = 80
    instance_protocol = "http"
  }
}

or

...
  subnets = ["${split(",", join(",", module.subnets.subnets["public"]))}"]
...

_modules/test/module.tf_

data "null_data_source" "subnets" {
  inputs = {
    public = ["subnet-abcd1234","subnet-abcd1235","subnet-abcd1236"]
  }
}

output "subnets" {
  value = "${data.null_data_source.subnets.input}"
}

Debug Output

https://gist.github.com/nusnewob/b3230d0d83c40917516a068b3532092f

Expected Behavior

Should be able to pass the module output as list variable

Actual Behavior

Error refreshing state: 1 error(s) occurred:

* inputs: 1 error(s) decoding:

* '[public]' expected type 'string', got unconvertible type '[]interface {}'

Steps to Reproduce

  1. terraform apply or terraform plan
bug providenull

Most helpful comment

I have problems with this too even in terraform v0.8. If I output a literal list as in @fmasuhr example everything works fine, but if instead I use something like this:

output "subnets-public" {
    value = [ "${aws_subnet.public.*.id}" ]
}

then terraform doesn't seem to work in few places, example the length interpolation fails.

All 14 comments

Hi @nusnewob! Thank you for the detailed description - I can reproduce this from the configuration you gave. I'll be working on a reduction and fix for this over the course of today.

Any updates on this issue?

Workaround: "serialize" to string and then "deserialize"

output "subnet_ids" {
  value = "${join(",", aws_subnet.with_az_index.*.id)}"
}
subnet_id = "${element(split(",", module.mymodule.subnet_ids), count.index)}"

If you change the output to a list instead of map, it works also without join and split.
It seems like the map of lists is not working properly here.

modules/test/module.tf

output "subnets-public" {
  value = ["subnet-abcd1234", "subnet-abcd1235", "subnet-abcd1236"]
}

maint.tf

subnets = ["${data.terraform_remote_state.config.private_subnet_ids}"]
module "subnets" {
  source = "./modules/test"
}

resource "aws_elb" "elb" {
  name = "test"
  subnets = ["${module.subnets.subnets-public}"]
  ...
}

I have problems with this too even in terraform v0.8. If I output a literal list as in @fmasuhr example everything works fine, but if instead I use something like this:

output "subnets-public" {
    value = [ "${aws_subnet.public.*.id}" ]
}

then terraform doesn't seem to work in few places, example the length interpolation fails.

I have the same problem with @jfromaniello. It says aws_elb.ELB: ValidationError: Only one of SubnetIds or AvailabilityZones may be specified.

@jfromaniello are you interpolating length in a count?

@osalkk the ELB validation error is separate - can you post the configuration for that resource?

Hi @jen20. Thanks in advance.

This is the output:
output "public_subnet_id" {
value = ["${aws_subnet.demo_vpc_public_subnet.*.id}"]
}

and the result for the output :
subnets = [
subnet-435ed12b,
subnet-b0ef3cca
]

When I use it for my elb module it says "aws_elb.ELB: ValidationError: Only one of SubnetIds or AvailabilityZones may be specified."
This is the module where I want to use with elb:
module "External_ELB" {
source = "../elb"
name = "External-ELB"
target = "index.html"
elb_listener_port = 80
instance_port = 80
subnets = ["${module.Prod_VPC.public_subnet_id}"]
}
And the resource for elb:

resource "aws_elb" "ELB" {

name = "${var.name}"
availability_zones = ["eu-central-1a","eu-central-1b"]
subnets = ["${var.subnets}"]
.....
}

Ok I found it, I was using both availability_zones and subnets. By removing availability_zones ( which is only used for ec2-classic elb ) it is resolved.

I'm also currently experiencing this problem with Terraform v0.8.5. Although I'm also seeing this behaviour even when implicitly attempting to create a list from several outputs.

Take for example the following outputs:

output "external_elb_name" {
  value = "${aws_elb.external.name}"
}
output "internal_elb_name" {
  value = "${aws_elb.internal.name}"
}
output "internal_alt_elb_name" {
  value = "${aws_elb.internal_alt.name}"
}

And then creating a list of these outputs:

load_balancers  = [
  "${module.elbs.external_elb_name}",
  "${module.elbs.internal_elb_name}",
  "${module.elbs.internal_alt_elb_name}"
]

Which eventually fails with:

Errors:

  * aws_autoscaling_group.asg: load_balancers: should be a list

If I change those output definitions to refer to the modules input variables for instance, or some fixed string, etc, they work without issue. It's only a problem when they refer to the resource outputs.

I believe this has been fixed (v 0.8.6) provided that relevant variables are declared with type="list" and wrapped in [] when passed to resources

I am using v 0.8.7, have set the time and passing brackets - and have the same issue.

@tomdavidson Have you tried to wrap all places where your list used with brackets? I had a similar problem and I managed to solve it by adding brackets in all below:

  • module A output
output "public_subnets_ids" {
  value = ["${aws_subnet.public.*.id}"]
}
  • module B input
module "gateway" {
  source             = "../../stack/gateway"
  public_subnet_ids  = ["${module.vpc.public_subnets_ids}"]
}
  • module B resource
variable "public_subnet_ids" {
  type        = "list"
  description = "Public Subnet IDs"
}

resource "aws_elb" "main" {
  name            = "${var.environment}-${var.role}"
  subnets         = ["${var.public_subnet_ids}"]
}

I am using 0.8.7 version.

@gruzewski my problem ended up related to https://github.com/hashicorp/hil/issues/50 - HIL evaluates both branches of a condition.

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.

Was this page helpful?
0 / 5 - 0 ratings