terraform:通过模块传递列表,得到“错误:...应该是一个列表"; [英] terraform: passing list through modules, getting "Error:... should be a list"
问题描述
ETA:在 terraform github 问题中找到讨论,https://github.com/hashicorp/terraform/issues/13103.已知且非常...特殊"...问题.
<小时>通过其他两个模块(从 top.tf
到 autoscaling_group
到 launch_configuration
)传递一个列表后,这两个模块都将变量定义为type = "list"
,我收到了来自 terraform plan
的以下投诉:
错误:module.autoscaling_group.aws_launch_configuration.this:security_groups:应该是一个列表"
它似乎将参数识别为列表类型(如果我从变量声明中删除类型规范,它会抱怨).但我发现消除错误的唯一方法是将最终用法包含在列表括号中.这似乎违反直觉(当我这样做时,我还没有看到 apply
会发生什么) - 发生了什么?
顺序:
top.tf
调用security_group
.top.tf
还调用autoscaling
,传递带有安全组id
输出的列表.autoscaling
调用launch_configuration
,传递参数.
这是布局,下面是.tf文件的内容.
<代码>.├── autoscaling_group│ └── main.tf├── 启动配置│ └── main.tf├── 安全组│ └── main.tf└── top.tf
top.tf
中的初始调用是:
模块autoscaling_group"{源 =启动配置"security_groups = ["${module.security_group.id}"]}
有问题的用法在 launch_configuration/main.tf
:
资源aws_launch_configuration"this"{name_prefix = "foobar"image_id = "this_is_fake"instance_type = "ts.small"security_groups = "${var.security_groups}"}
- 如果我添加括号:
["${var.security_groups}"]
我没有收到错误. - 如果我从
launch_configuration/main.tf
的变量定义块中删除type = "list"
,terraform plan
会报错:module.autoscaling_group.var.security_groups:模块autoscaling_group中的变量security_groups应该是字符串类型,得到列表
top.tf
的内容:
提供者aws"{地区=我们-东-1"}模块安全组"{源 =安全组"}模块自动缩放组"{源 =启动配置"security_groups = ["${module.security_group.id}"]}
autoscaling_group/main.tf
的内容:
变量security_groups"{类型=列表"description = "附加到已启动实例的安全组."}模块启动配置"{源 =启动配置"security_groups = "${var.security_groups}"}资源aws_autoscaling_group"service_autoscaling_group"{name_prefix = "foobar"min_size = 1最大尺寸 = 1health_check_type = "EC2"启动配置 = "${module.launch_configuration.name}"vpc_zone_identifier = [this_is_fake"]}
launch_configuration/main.tf
的内容:
变量security_groups"{类型=列表"description = "附加到已启动实例的安全组."}输出名称"{值 = "${aws_launch_configuration.this.name}"}资源aws_launch_configuration"这个"{name_prefix = "foobar"image_id = "this_is_fake"instance_type = "ts.small"security_groups = "${var.security_groups}"}
再一次,如果我在最后一个赋值 ["${var.security_groups}"]
的 RHS 周围加上括号,我看不到 terraform plan
.但是 terraform 将变量识别为列表(因为如果我从声明中删除 type = "list"
,它会抱怨它是列表类型).那么为什么它抱怨它需要一个列表呢?
security_group/main.tf
的内容:
输出id"{值 = "${aws_security_group.this.id}"description = "安全组 ID."}资源aws_security_group"这个"{name_prefix = "foobar"vpc_id = "this_is_fake"描述=foobar"出口{从端口 = 0to_port = 0协议 =-1"cidr_blocks = [0.0.0.0/0"]}}
我遇到了同样的问题,应该在 v0.12 中解决:https://github.com/hashicorp/terraform/issues/18923#issuecomment-434901762
如果您想将列表作为模块参数传递,这里有一个小技巧.我只是发送一个字符串,然后将其解析为一个列表(AWS Backup 模块的示例):
<块引用>terraform.tf
模块你的模块"{源 = "./module_path"list_as_string = "${var.element_1};${var.element_1}"}
<块引用>
./module_path/variables.tf
变量list_as_string"{description = "字符串列表"}
<块引用>
./module_path/main.tf
资源资源"示例"{real_list = ["${split(";", var.list_as_string)}"]}
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
callssecurity_group
.top.tf
also callsautoscaling
, passing a list with the security groupid
output.autoscaling
callslaunch_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}"
}
- If I add brackets:
["${var.security_groups}"]
I don't get the error. - If I remove the
type = "list"
from the variable definition block inlaunch_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)}"]
}
这篇关于terraform:通过模块传递列表,得到“错误:...应该是一个列表";的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!