【问题标题】:Creating multiple SecurityGroups / Rules in AWS using Terraform使用 Terraform 在 AWS 中创建多个安全组/规则
【发布时间】:2022-02-07 19:25:57
【问题描述】:

我正在尝试在 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_sg 和external_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".
╵

【问题讨论】:

  • 到底发生了什么?有什么错误吗?
  • 我相信我的逻辑是错误地迭代规则并得到这个

标签: amazon-web-services terraform terraform-provider-aws hcl


【解决方案1】:

你必须先展平你的变量:


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
}

【讨论】:

  • 先生,你用规则做了一些很棒的 VOODOO,但我们被困在一个点上,它需要一个安全组 ID 而不是名称。
  • 所以这一行security_group_id = aws_security_group.ec2_security_groups[each.value.sg_name] 期望准确的 sg 名称 id 继续前进
  • @Ali 更新了答案。
猜你喜欢
  • 2020-10-15
  • 2019-07-11
  • 1970-01-01
  • 2019-07-28
  • 2020-10-06
  • 1970-01-01
  • 2020-03-27
  • 2021-03-06
相关资源
最近更新 更多