ETA: Found discussion in terraform github issues, https://github.com/hashicorp/terraform/issues/13103. Known and very... "idiosyncratic"... issue.
After passing a list through two other modules (from top.tf
through autoscaling_group
to launch_configuration
), both of which define the variable as type = "list"
, I'm getting the following complaint from terraform plan
:
"Error: module.autoscaling_group.aws_launch_configuration.this:
security_groups: should be a list"
It seems to recognize the parameter as a list type (if I remove the type specification from the variable declaration, it complains). But the only way I find to silence the error is to wrap the final usage in list brackets. This seems counterintuitive (and I haven't seen what happens with apply
when I do so) - what's going on?
The sequence:
top.tf
calls security_group
.top.tf
also calls autoscaling
, passing a list with the security group id
output.autoscaling
calls launch_configuration
, passing the parameter through.Here's the layout, contents of .tf files is below.
.
├── autoscaling_group
│ └── main.tf
├── launch_configuration
│ └── main.tf
├── security_group
│ └── main.tf
└── top.tf
The initiating call in top.tf
is:
module "autoscaling_group" {
source = "launch_configuration"
security_groups = ["${module.security_group.id}"]
}
The offending usage is in launch_configuration/main.tf
:
resource "aws_launch_configuration" "this" {
name_prefix = "foobar"
image_id = "this_is_fake"
instance_type = "ts.small"
security_groups = "${var.security_groups}"
}
["${var.security_groups}"]
I don't get the error.type = "list"
from the variable definition block in launch_configuration/main.tf
, terraform plan
complains: module.autoscaling_group.var.security_groups: variable security_groups in module autoscaling_group should be type string, got list
The content of top.tf
:
provider "aws" {
region = "us-east-1"
}
module "security_group" {
source = "security_group"
}
module "autoscaling_group" {
source = "launch_configuration"
security_groups = ["${module.security_group.id}"]
}
The content of autoscaling_group/main.tf
:
variable "security_groups" {
type = "list"
description = "The security groups to attach to launched instances."
}
module "launch_configuration" {
source = "launch_configuration"
security_groups = "${var.security_groups}"
}
resource "aws_autoscaling_group" "service_autoscaling_group" {
name_prefix = "foobar"
min_size = 1
max_size = 1
health_check_type = "EC2"
launch_configuration = "${module.launch_configuration.name}"
vpc_zone_identifier = ["this_is_fake"]
}
The content of launch_configuration/main.tf
:
variable "security_groups" {
type = "list"
description = "The security groups to attach to launched instances."
}
output "name" {
value = "${aws_launch_configuration.this.name}"
}
resource "aws_launch_configuration" "this" {
name_prefix = "foobar"
image_id = "this_is_fake"
instance_type = "ts.small"
security_groups = "${var.security_groups}"
}
Again, if I wrap brackets around the RHS of the last assignment ["${var.security_groups}"]
, I don't see the error from terraform plan
. But terraform recognizes the variable as a list (since it complains about it being a list type if I remove the type = "list"
from the declaration). So why does it complain that it expects a list here?
The content of security_group/main.tf
:
output "id" {
value = "${aws_security_group.this.id}"
description = "The security group ID."
}
resource "aws_security_group" "this" {
name_prefix = "foobar"
vpc_id = "this_is_fake"
description = "foobar"
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
I had the same issue, it should be resolved in the v0.12 : https://github.com/hashicorp/terraform/issues/18923#issuecomment-434901762
If you want to pass a list as module parameter here is a small hack to do it. I just send a string and then parse it to a list (Example with AWS Backup module) :
terraform.tf
module "your_module" {
source = "./module_path"
list_as_string = "${var.element_1};${var.element_1}"
}
./module_path/variables.tf
variable "list_as_string" {
description = "List in string"
}
./module_path/main.tf
resource "resource" "exemple" {
real_list = ["${split(";", var.list_as_string)}"]
}