获取一组子网的 CIDR 块
Getting the CIDR block of a set of subnets
我正在尝试获取一组提供参数的子网 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
感谢能提供帮助的人!
您应该对地图的值使用 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}"
}
}
我认为这里的问题是 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]
我正在尝试获取一组提供参数的子网 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
感谢能提供帮助的人!
您应该对地图的值使用 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}"
}
}
我认为这里的问题是 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]