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

Unable to use output variable as list #8048

Closed
nusnewob opened this issue Aug 8, 2016 · 14 comments
Closed

Unable to use output variable as list #8048

nusnewob opened this issue Aug 8, 2016 · 14 comments

Comments

@nusnewob
Copy link

nusnewob commented Aug 8, 2016

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
nusnewob added a commit to uktrade/terraform-modules that referenced this issue Aug 8, 2016
@jen20 jen20 added the core label Aug 8, 2016
@jen20 jen20 self-assigned this Aug 8, 2016
@phinze phinze added the bug label Aug 8, 2016
@jen20
Copy link
Contributor

jen20 commented Aug 8, 2016

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.

@matti
Copy link

matti commented Sep 28, 2016

Any updates on this issue?

@matti
Copy link

matti commented Sep 28, 2016

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)}"

@fmasuhr
Copy link

fmasuhr commented Oct 20, 2016

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}"]
  ...
}

@jfromaniello
Copy link
Contributor

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.

@osalkk
Copy link

osalkk commented Dec 20, 2016

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

@jen20
Copy link
Contributor

jen20 commented Dec 20, 2016

@jfromaniello are you interpolating length in a count?

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

@osalkk
Copy link

osalkk commented Dec 20, 2016

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.

@cewood
Copy link
Contributor

cewood commented Feb 2, 2017

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.

@ValFadeev
Copy link
Contributor

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

@tomdavidson
Copy link

tomdavidson commented Feb 9, 2017

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

@gruzewski
Copy link

gruzewski commented Feb 27, 2017

@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.

@tomdavidson
Copy link

@gruzewski my problem ended up related to hashicorp/hil#50 - HIL evaluates both branches of a condition.

@ghost
Copy link

ghost commented Apr 10, 2020

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.

@ghost ghost locked and limited conversation to collaborators Apr 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests