使用 Terraform 在 AWS 中创建多个安全组/规则

Creating multiple SecurityGroups / Rules in AWS using Terraform

我正在尝试在 AWS 的一个模块中同时在此组中创建多个安全组和规则。

我有一个像下面这样的变量类型

variable "security_rules" {

      type = map(map(object({
        type        = string
        description = string
        from_port   = number
        to_port     = number
        protocol    = string
        cidr_blocks = list(string)
      })))
    }

我正在传递这样的值

security_rules = {
  internal_sg = {
    "rule1" = { type = "ingress", from_port = 22, to_port = 22, protocol = "tcp", cidr_blocks = ["0.0.0.0/0"], description = "For SSH" },
    "rule2" = { type = "ingress", from_port = 22, to_port = 22, protocol = "tcp", cidr_blocks = ["0.0.0.0/0"], description = "For SSH" }
  external_sg = {
    "rule1" = { type = "ingress", from_port = 22, to_port = 22, protocol = "tcp"
  }
}

其中internal_sgexternal_sg是安全组名和对应的规则

我可以创建安全组,但无法在其上添加规则。

locals {
  name = var.security_rules
}

resource "aws_security_group" "ec2_security_groups" {
  for_each = local.name
  name   = each.key
  vpc_id = data.aws_vpc.selected.id
}
 

但是我无法为安全组规则制定逻辑

resource "aws_security_group_rule" "rules" {
  for_each          = { for k, v in local.name : k => v }
  type              = each.value.type
  from_port         = each.value.from_port
  to_port           = each.value.to_port
  protocol          = each.value.protocol
  cidr_blocks       = each.value.cidr_blocks
  description       = each.value.description
  security_group_id = aws_security_group.ec2_security_groups[each.key]
}

错误:

╷
│ Error: Missing map element
│ 
│   on ../../terraform-stacks/Stacks/security-group/main.tf line 19, in resource "aws_security_group_rule" "rules":
│   19:   type              = each.value.type
│     ├────────────────
│     │ each.value is map of object with 3 elements
│ 
│ This map does not have an element with the key "type".
╵

你必须先展平你的变量:


locals {
  flat_security_rules = merge([
      for sg, rules in var.security_rules:
         {
           for rule, vals in rules:
             "${sg}-${rule}" => merge(vals, {sg_name = sg})
         }
    ]...) # please, do NOT remove the dots
}

然后

resource "aws_security_group_rule" "rules" {
  for_each          = local.flat_security_rules
  type              = each.value.type
  from_port         = each.value.from_port
  to_port           = each.value.to_port
  protocol          = each.value.protocol
  cidr_blocks       = each.value.cidr_blocks
  description       = each.value.description
  security_group_id = aws_security_group.ec2_security_groups[each.value.sg_name].id
}