我正在尝试获取一组提供参数的子网ID的CIDR块。
data "aws_subnet" "target" {
for_each = "${toset(var.subnet_ids)}"
id = "${each.value}"
}
resource "aws_security_group" "registry" {
vpc_id = "${var.vpc_id}"
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["${data.aws_subnet.target.*.cidr_block}"]
}
tags = {
Name = "${var.name}"
}
}
我得到的错误是:
cidr_blocks = "${data.aws_subnet.target.*.cidr_block}"
This object does not have an attribute named "cidr_block".
Terraform配置:
Terraform v0.12.24
+ provider.aws v2.55.0
+ provider.template v2.1.2
感谢任何可以提供帮助的人!
答案 0 :(得分:0)
您应该对地图的值使用splat表达式。
resource "aws_security_group" "registry" {
vpc_id = "${var.vpc_id}"
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = values(data.aws_subnet.target).*.cidr_block
}
tags = {
Name = "${var.name}"
}
}
答案 1 :(得分:0)
我认为这里的问题在于,for_each
参数使data.aws_subnet.target
出现为地图值,并且将splat运算符.*
定义为无操作(如果应用)除列表或集合以外的任何内容。因此,这里的表达式评估采取以下步骤:
data.aws_subnet.target
,生成对象图,其键是来自var.subnet_ids
的字符串,大概看起来像subnet-12345
。.*
应用于该地图。因为它是一张地图,所以会再次产生相同的结果。.cidr_block
应用于该映射,该映射将失败,因为其键是子网ID,而不是子网对象的属性。要在此处获得所需的结果,我们可以使用values
忽略键,并将地图中的值作为列表:
cidr_blocks = values(data.aws_subnet.target).*.cidr_block
由于values(...)
的结果是一个列表,因此.*
运算符将按预期方式运行,并尝试在列表的每个元素中找到cidr_block
属性。
另一种选择是使用for
expression,它是适用于任何集合类型值的splat语法的概括:
cidr_blocks = [for s in data.aws_subnet.target : s.cidr_block]