我有一组9个安全组规则,需要将它们应用于4个不同的来源。我想将其构建为模块,因此无需将端口和源作为变量传递,而不必多次复制/粘贴同一块。
我尝试创建一个模块,以在动态块中将端口获取为for_each
,并通过count
传递源,因为我无法通过for_each
提供附加的动态块也用于来源。
resource "aws_security_group" "test" {
name = "test2"
count = length(var.groups)
vpc_id = var.vpc_id
dynamic "ingress_tcp" {
for_each = var.tcp_ports
content {
from_port = ingress_tcp.value
to_port = ingress_tcp.value
protocol = "tcp"
security_groups = [var.groups[*].id]
}
}
dynamic "ingress_udp" {
for_each = var.udp_ports
content {
from_port = ingress_udp.value
to_port = ingress_udp.value
protocol = "udp"
security_groups = [var.groups[*].id]
}
}
}
module "rules" {
source = "./module/sg"
vpc_id = var.vpc_id
name = "tomer-test"
tcp_ports = var.tcp_ports
udp_ports = var.udp_ports
groups = [var.groups[*].id]
}
variable "groups" {
description = "source groups"
type = "list"
default = [{
name = "Enforcement-STG",
id = "sg-c9db2183abcd"
},
{
name = "Managment-STG",
id = "sg-b0e71dfa123"
}]
}
variable "name" {
type = string
}
variable "vpc_id" {
type = string
default = ""
}
variable "tcp_ports" {
description = "tcp ports to open"
default = [514,1514, 11514, 12514, 6514]
}
variable "udp_ports" {
description = "tcp ports to open"
default = [514,1514, 11514, 12514]
}
我接受为每个源组构建一组规则的输出,但是根模块无法调用该模块。 我当前遇到的错误是
terraform plan
Error: Unsupported block type
on module/sg/main.tf line 7, in resource "aws_security_group" "test":
7: dynamic "ingress_tcp" {
Blocks of type "ingress_tcp" are not expected here.
Error: Unsupported block type
on module/sg/main.tf line 16, in resource "aws_security_group" "test":
16: dynamic "ingress_udp" {
Blocks of type "ingress_udp" are not expected here.
答案 0 :(得分:0)
如错误消息所暗示,您在此处尝试的操作无效,因为ingress_tcp
不是aws_security_group
资源内部预期的块类型。此嵌套块类型的正确名称为ingress
:
resource "aws_security_group" "test" {
count = length(var.groups)
name = "test2"
vpc_id = var.vpc_id
dynamic "ingress" {
for_each = var.tcp_ports
content {
from_port = ingress.value
to_port = ingress.value
protocol = "tcp"
security_groups = var.groups[*].id
}
}
dynamic "ingress" {
for_each = var.udp_ports
content {
from_port = ingress.value
to_port = ingress.value
protocol = "udp"
security_groups = var.groups[*].id
}
}
}
如果您使用的是Terraform 0.12.6或更高版本,则可能更喜欢使用资源for_each
而不是count
来编写,就像这样:
resource "aws_security_group" "test" {
for_each = { for g in var.groups : g.name => g }
name = "test2-${each.key}"
vpc_id = var.vpc_id
dynamic "ingress" {
for_each = var.tcp_ports
content {
from_port = ingress.value
to_port = ingress.value
protocol = "tcp"
security_groups = var.groups[*].id
}
}
dynamic "ingress" {
for_each = var.udp_ports
content {
from_port = ingress.value
to_port = ingress.value
protocol = "udp"
security_groups = var.groups[*].id
}
}
}
这将与您的count
示例产生相似的结果,但是将生成地址为aws_security_group.test["Enforcement-STG"]
而不是aws_security_group.test[0]
的实例,这意味着您在{{ 1}},将来Terraform将能够确定与每个元素对应的实例,而仅添加/删除所需的单个实例。
基于此地图的资源也可能更易于在配置中的其他位置使用,因为您将能够轻松找到每个符号组名称的特定安全组。