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

Error: security_groups: should be a list. in AWS_LAUNCH_CONFIGURATION API #13869

Closed
cheburakshu opened this issue Apr 22, 2017 · 31 comments
Closed

Comments

@cheburakshu
Copy link

I am on Terraform v0.9.2.

I get error security_groups: should be a list eventhough it is supplied as a list. Seems the issue was addressed with #691 but it is surfacing now for me. I have added my snippets to #691 for reproducing the error.

@cheburakshu
Copy link
Author

Same behavior on aws_auto_scaling_group too.
It will not accept unless explicitly passed over as a list.

@stack72
Copy link
Contributor

stack72 commented Apr 23, 2017

Hi @cheburakshu , to better understand the issue & make it easier to reproduce for anyone else would you mind sharing more details? e.g.

  • terraform config you ran (minus any secrets)
  • full output (stdout + stderr) from terraform commands you ran (minus any secrets)
  • debug log from terraform commands you ran (minus any secrets)

Thanks.

@stack72

@cheburakshu
Copy link
Author

Please clone this repo -- github.com/cheburakshu/terrakube.
The config file has no secrets. Uses AWS RSA Keys (a config param). run.sh is the entry point for the modules.
Now this fails on autoscaling_group tag.
I have same issue on these modules - aws_launch_configuration [security_groups], aws_autoscaling_group [vpc_zone_identifier, tag], aws_instance [vpc_security_group_ids].
Please let me know if you need more info.
The way I moved on with the other error is listed in the below snippet.

I am on Terrform v0.9.2

module "launch_configuration" {
  source = "./modules/aws_launch_configuration"
  name = "${module.cluster.asg_name}"
  image_id = "${var.images[var.region]}"
  iam_instance_profile = "${module.cluster.id}"
  instance_type = "${var.size["minion"]}"
  key_name = "${module.key_pair.key_name}"
# There is a bug. This is not allowing me to send a list.
  security_groups = ["${module.minion_security_group.id}"]
  associate_public_ip_address = "${var.associate_public_ip_address}"
  spot_price = "${var.spot_price}"
  user_data = ""
}

Module:

variable "name" {}
variable "image_id" {}
variable "iam_instance_profile" {}
variable "instance_type" {}
variable "key_name" {}
variable "security_groups" {type="list"}
variable "associate_public_ip_address" {}
variable "spot_price" {}
variable "user_data" {}

resource "aws_launch_configuration" "aws_launch_configuration" {
  name = "${var.name}"
  image_id = "${var.image_id}"
  iam_instance_profile = "${var.iam_instance_profile}"
  instance_type = "${var.instance_type}"
  key_name = "${var.key_name}"
  security_groups = "${var.security_groups}"
  associate_public_ip_address = "${var.associate_public_ip_address}"
  spot_price = "${var.spot_price}"
  user_data = "${var.user_data}"
}

Output:

1 error(s) occurred:

* module.launch_configuration.aws_launch_configuration.aws_launch_configuration: security_groups: should be a list

Change security groups as a list, explicitly in module:

variable "name" {}
variable "image_id" {}
variable "iam_instance_profile" {}
variable "instance_type" {}
variable "key_name" {}
variable "security_groups" {type="list"}
variable "associate_public_ip_address" {}
variable "spot_price" {}
variable "user_data" {}

resource "aws_launch_configuration" "aws_launch_configuration" {
  name = "${var.name}"
  image_id = "${var.image_id}"
  iam_instance_profile = "${var.iam_instance_profile}"
  instance_type = "${var.instance_type}"
  key_name = "${var.key_name}"
# Change as explicit list
  security_groups = ["${var.security_groups}"]
  associate_public_ip_address = "${var.associate_public_ip_address}"
  spot_price = "${var.spot_price}"
  user_data = "${var.user_data}"
}

And it works!

Get: file:///home/sud/cloud/projects/terrakube/modules/aws_launch_configuration
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

@catsby
Copy link
Contributor

catsby commented Apr 24, 2017

Hey @cheburakshu – the second example is how you are required to reference lists

example: something = ["${var.LIST}"]

@catsby catsby closed this as completed Apr 24, 2017
@cheburakshu
Copy link
Author

cheburakshu commented Apr 24, 2017

@catsby
I don't think your answer is accurate. I am using a module with a variable defined as a list.
The calling .tf can pass a simple list or a list of maps. Refer below for dhcp where it accepts. Many such examples I have where the module fields will not accept list or list of maps. The behavior is inconsistent.

See the example below - This works. Note domain_name_servers is a list.

variable "domain_name" {}
variable "domain_name_servers" {type="list"}
variable "tags" {type="map"}

resource "aws_vpc_dhcp_options" "aws_vpc_dhcp_options" {
  domain_name = "${var.domain_name}"
  domain_name_servers = "${var.domain_name_servers}"
  tags = "${var.tags}"
}
variable "security_groups" {type="list"}
...
  security_groups = "${var.security_groups}" **ERROR**
...

This is what is getting passed -

security_groups = ["${module.minion_security_group.id}"]

@cheburakshu
Copy link
Author

cheburakshu commented Apr 24, 2017

@catsby Can this be re-opened. I am not setting a wrong value here. Need help. You can see the code here- github.com/cheburakshu/terrakube

@catsby
Copy link
Contributor

catsby commented Apr 25, 2017

Hey @cheburakshu if you can extract from your example repo a minimal configuration ( a default map value, with something like aws_instance) that demonstrates this issue, I can reopen and investigate. I'm afraid that downloading your repository, which appears to be a work in progress or at least a repository that is not solely created for demonstrating this issue, and digging into your modules is beyond the support I can provide at this time. You may have more luck on our mailing list or over at Stack Overflow.

I sincerely want to help, but I need a more narrow, specific example to be provided.

@jrandall
Copy link

@catsby I had this problem as well and I agree with @cheburakshu that it is a problem, either with the documentation or the implementation, depending on which one is right.

The documentation you linked to (https://www.terraform.io/docs/configuration/interpolation.html#user-list-variables) says:

User list variables

The syntax is "${var.LIST}". For example, "${var.subnets}" would get the value of the subnets list, as a list.

But it appears that in this case at least we are required to reference a list as ["${var.subnets}"] - that is definitely not clear from the documentation. If it is the correct behavior, perhaps just a fix to those docs is in order?

@jrandall
Copy link

On further consideration, I think the docs are right and the behavior is wrong. The way we apparently need to surround some list interpolations with square brackets would hide real problems in case the variable passed into the module mistakenly is not a list (i.e. it would convert a string variable into a list of length one rather than giving an error).

@cheburakshu
Copy link
Author

cheburakshu commented Jun 10, 2017 via email

@rszalski
Copy link

I have just experienced the same issue and agree with @jrandall 's previous 2 comments. Moreover, the issue does not appear when the initial list is created in place, without any variables.

Using: terraform v0.10.2

@catsby I've created a minimal working example repo: https://github.com/rszalski/terraform_list_var_inconsistency I hope it's minimal enough for you to consider reopening and investigating.

@geoffreywiseman
Copy link
Contributor

geoffreywiseman commented Sep 6, 2017

This is at the very least a documentation issue and, I agree, if the documentation were updated to match the only thing that works (e.g. param = [ "${var.VARNAME}" ]), it's likely to paper over potential problems, so I'd rather see the implementation fixed. @jrandall @rszalski are on the right path, and issue should be re-opened.

Problem occurs with Terraform v0.10.3 as well.

@huntercatalan
Copy link

+1

this problem makes using modules stupid, coupled with issue for just-in-time count expansion: #1497 (comment)

kospant pushed a commit to kospant/terraform-aws-autoscaling that referenced this issue Oct 2, 2017
kospant pushed a commit to kospant/terraform-aws-autoscaling that referenced this issue Oct 2, 2017
@whatisaphone
Copy link

I can confirm being befuddled for several minutes by this bug.

dshmelev pushed a commit to dshmelev/terraform-aws-cloudformation-autoscaling that referenced this issue Nov 22, 2017
dshmelev pushed a commit to dshmelev/terraform-aws-cloudformation-autoscaling that referenced this issue Nov 22, 2017
@Mistobaan
Copy link

just got this confusing error too. the right way to reference a variable is ["${var.listvariable}"] but the documentation says "${var.listvariable}".

@bbakersmith
Copy link

this is a bug and should be reopened. my list variable inside a module works without brackets unless the list that's passed in contains a variable, then i have to put brackets around the reference in the module. weird stuff.

@zach-b
Copy link

zach-b commented Jan 26, 2018

I just faced this too. This is definitely confusing and I believe the issue should be reopened.

@petewilcock
Copy link

+1 this is a definite bug seemingly when passing lists into modules.

Simple example:
security_groups = ["sg-123456"] - Works

security_groups = ["${data.terraform_remote_state.root_module.prod-web-sg-id}"] - Complains security_groups is not a list

I also tried a couple of things like calling trimspace() on the interpolated variable to see if that would resolve some kind of typing mismatch, but nope. Something deeper going on that's not self-evident. I disagree that the module definition should be a list to which a string value is passed - not a good workaround and horrible if you have existing module instantiations.

@cannontrodder
Copy link

It's trivial to reproduce this as @petewilcock has shown - you'd expect "sg-123456" to be equivalent to "${var.sg}" if var.sg is equal to "sg-123456". It's a one-line terraform plan, what other repo steps are needed?

@whatisaphone
Copy link

@catsby Unfortunately this is still an issue. The docs say this:

User list variables

The syntax is "${var.LIST}". For example, "${var.subnets}" would get the value of the subnets list, as a list. You can also return list elements by index: ${var.subnets[idx]}.

It would be great if this were true, but it's not ☹️. If you follow the docs, your code will break. Assuming that subnets is a list, "${var.subnets}" (as mentioned in the docs) will cause an error if you pass it to a variable expecting a list. However, unintuitively, passing ["${var.subnets}"] will work. This correct syntax is not mentioned in the docs.

This can be demonstrated in the minimal repro that @rszalski kindly took the time to put together last August. Here's the important file (it's only 7 lines long).

Since the docs don't match the behavior, there are two possible resolutions here:

  1. Update the docs to match current behavior
  2. Update the behavior to match the docs

I would strongly prefer the former, but if you guys choose the latter, at least your intent will be clear and this inconsistency could still be navigated by reading the docs.

In the meantime, could you please reopen this, add tags core and documentation, and remove tag provider/aws? AWS isn't the only provider with a module that accepts a key of type list. This is an HCL and/or docs issue. Thank you!

Sorry for tagging you, but I just want this to be solved before 1.0 so Terraform is the best it can be ❤️

@cheburakshu
Copy link
Author

After I met with this bug, I consciously moved away from writing modules since they are very brittle in behavior (due to parsing of list, list of maps etc) when compared to the resources themselves.

Another major missing feature, though un-related to my original filing of this bug report, is the inability of modules to be used for creating multiple resources. The explosion operation '*', works with resources like a charm and the hope for it to be available in modules is just a distant dream.

Anyway, hope this gets fixed.

@vdoodala
Copy link

I faced this issue too... cannot pass type = "list" in the modules... I like the whole modules, how they work.. these little things need to be fixed for better reusability.

@labkey-ians
Copy link

labkey-ians commented May 10, 2018

@catsby why have typed variables if the type isn't respected.
https://www.terraform.io/docs/configuration/interpolation.html#user-list-variables

app/alb.tf

module "alb" {
  source = "../alb"

  alb_name = "live-alb"
  alb_subnets = [
    "${aws_subnet.public_subnet.id}",
    "${aws_subnet.public_alternate_subnet.id}"
  ]
  alb_security_groups = [
    "${aws_security_group.internet_access.id}",
    "${aws_security_group.alb_sg.id}"
  ]
}

module alb/alb.tf

variable "alb_subnets" {
  type = "list"
  description = "List of subnets the ALB is connected to"
}

// ALB and associated resources
resource "aws_alb" "alb"
{
  name = "${var.alb_name}"
  internal        = false
  idle_timeout    = 600
  subnets         = "${var.alb_subnets}"
  security_groups = "${var.alb_security_groups}"

  tags = "${var.alb_tags}"
}

Error: module.alb.aws_alb.alb: security_groups: should be a list
Error: module.alb.aws_alb.alb: subnets: should be a list

@cabeaulac
Copy link

I also just hit this issue again.

whatisaphone pushed a commit to whatisaphone/terraform that referenced this issue May 16, 2018
This fixes a mismatch between docs and behavior. Although the described behavior is unintuitive, it matches the reality of how Terraform currently works. hashicorp#13869 has further details and a small repo where you can quickly verify the behavior we're seeing.

I hope that the bug is fixed and this commit can be rolled back, but in the meantime, I think it would be good for the docs to be accurate to prevent confusion.
@whatisaphone
Copy link

whatisaphone commented May 16, 2018

I submitted a PR to describe the current behavior in the docs in lieu of a bugfix.

While I'm here, I'd also like to once again bring attention to the minimal repro that @rszalski kindly took the time to put together last August. Here's the key file in its entirety:

resource "aws_instance" "list-example-ec2" {
  ami                       = "ami-d7b9a2b1"
  instance_type             = "t2.nano"
  vpc_security_group_ids    = "${var.security_group_ids}"
  # However the following works (notice the surrounding square brackets)
  # vpc_security_group_ids    = ["${var.security_group_ids}"]
}

Here is a link to the full repo: https://github.com/rszalski/terraform_list_var_inconsistency

@whatisaphone
Copy link

Looks like a fix for this issue is in the works: #18062 (comment)

@geoffreywiseman
Copy link
Contributor

I'm glad they're doing a real fix, although I'm also glad that your PR turned up more information on what's going on. ;)

@whatisaphone
Copy link

My devious plan worked perfectly :)

elenasharma pushed a commit to vmware-archive/terraforming-gcp that referenced this issue Nov 1, 2018
`Error: module.internetless.google_compute_firewall.cf-internal-egress:
destination_ranges: should be a list`

Terraform issue: hashicorp/terraform#13869

Signed-off-by: Elena Sharma <[email protected]>
cdutra pushed a commit to vmware-archive/terraforming-gcp that referenced this issue Nov 1, 2018
`Error: module.internetless.google_compute_firewall.cf-internal-egress:
destination_ranges: should be a list`

Terraform issue: hashicorp/terraform#13869

Signed-off-by: Elena Sharma <[email protected]>
bbeesley pushed a commit to bbeesley/terraform-aws-secret-manager-with-rotation that referenced this issue Feb 5, 2019
@JackDavidson
Copy link

Workaround:
Its not "${var.LIST}". use ["${var.LIST}"] (notice the extra square braces that the official documentation does not mention)

I can't believe the number of really obvious issues with terraform that have been declared not to be issues. This is like the 5th problem I've run into that was misunderstood by the hashicorp team and determined (incorrectly) to be user error for over a year.

The symptoms are that the type is a list and the expected type is a list, but terraform simply states 'should be a list' and does not mention what type was actually passed. When a variable of incorrect type is actually passed, the incorrect type is stated. for example ', got string'

@ChronosWS
Copy link

Also why have the 11.x docs not been updated since this issue was reported, verified (and even fixed in .12)?

@ghost
Copy link

ghost commented Jul 26, 2019

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 Jul 26, 2019
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