Terraform-迭代组合地图和列表



我想使用Terraform将列表和映射组合为AWS安全组的一组资源参数。对于端口列表中的每个端口,以及人员映射中的每个密钥,我希望在安全组中有一个Ingress规则。例如,我有一个(简化的(.tf,如下所示(我不知道的地方打问号(:

variable "IP_Mapping" {
type = "map"
default = {
"bob"          = "1.1.1.1/32"
"alice"        = "2.2.2.2/32"
}
}
variable "ingress_ports" {
type        = list(number)
description = "list of ingress ports"
default     = [80, 443]
}
resource "aws_security_group" "sg-vpc" {
name        = "sd-ocp-vpc_sg"
description = "Default security group"
vpc_id      = "${aws_vpc.vpc.id}"
ingress {
from_port   = ?
to_port     = ?
protocol    = "tcp"
cidr_blocks = ?
description = ?
}
}

我想要一个这样的静态资源:

resource "aws_security_group" "sg-vpc" {
name        = "sd-ocp-vpc_sg"
description = "Default security group"
vpc_id      = "${aws_vpc.vpc.id}"
ingress {
from_port   = 80
to_port     = 80
protocol    = "tcp"
cidr_blocks = ["1.1.1.1/32"]
description = "bob"
}
ingress {
from_port   = 443
to_port     = 443
protocol    = "tcp"
cidr_blocks = ["1.1.1.1/32"]
description = "bob"
}
ingress {
from_port   = 80
to_port     = 80
protocol    = "tcp"
cidr_blocks = ["2.2.2.2/32"]
description = "alice"
}
ingress {
from_port   = 443
to_port     = 443
protocol    = "tcp"
cidr_blocks = ["2.2.2.2/32"]
description = "alice"
}
}

我意识到入口块的顺序并不重要。如果有更好的方法我看不到的话,我也不会过度依赖地图/列表数据结构,只要我不必为每个用户列出每个端口(可能有很多端口,但对所有用户来说都是一样的(。

我已经将动态块用于ingress规则,并且可以找出如何在动态块中迭代映射,但在我的一生中都无法找到如何在动态资源参数中获得嵌套的for循环。

在构造动态块之前,可以先使用setproduct并创建一个helper_list


locals {
helper_list = setproduct(
var.ingress_ports,
[for name, cidr in var.IP_Mapping: [name, cidr]])           
}

local.helper_list的形式应为:

[
[
80,
[
"alice",
"2.2.2.2/32",
],
],
[
80,
[
"bob",
"1.1.1.1/32",
],
],
[
443,
[
"alice",
"2.2.2.2/32",
],
],
[
443,
[
"bob",
"1.1.1.1/32",
],
],
]

然后对于您的动态块:

resource "aws_security_group" "sg-vpc" {
name        = "sd-ocp-vpc_sg"
description = "Default security group"
vpc_id      = "${aws_vpc.vpc.id}"
dynamic "ingress" {
for_each = {for idx, item in local.helper_list: idx=>item}
content {
from_port   = ingress.value[0]
to_port     = ingress.value[0]
protocol    = "tcp"
cidr_blocks = [ingress.value[1][1]]
description = ingress.value[1][0]
}    
}
}

最新更新