Error: Cycle: local.security_groups (expand), aws_security_group.this

Error: Cycle: local.security_groups (expand), aws_security_group.this

需要帮助解决以下配置中的循环错误。我无法在任何安全组中找到对 workbench_service 的任何引用。 本地文件如下:

locals {
  security_groups = {
    ALB_Internal_rules_workbench_prod = {
      ingress = {
        WCC_user_redirect = {
          description = "Wcc Internal users connect to ALB_Internal_rules_workbench_prod"
          type        = "ingress"
          port        = 8080
          protocol    = "tcp"
          cidr_blocks = var.workstation_subnets
        }
        WCC_workspaces_redirect = {
          description = "Workspaces users connect to ALB_Internal_rules_workbench_prod"
          port        = 8080
          protocol    = "tcp"
          cidr_blocks = var.workspace_subnets
        }
      }
      egress = {
        all = {
          description = "Traffic to workbench service"
          type        = "egress"
          port        = 8080
          protocol    = "tcp"
          //cidr_blocks = ["10.103.8.0/24"]
          source_security_group_rule = aws_security_group.this["workbench_service"].id
        }
      }
    }
workbench_service = {
      ingress = {
        from_ALB_Internal_rules_workbench_prod = {
          description = "Traffic from ALB_Internal_rules_workbench_prod"
          type        = "ingress"
          port        = 8080
          protocol    = "tcp"
          //source_security_group = aws_security_group.this["ALB_Internal_rules_workbench_prod"].id
          cidr_blocks = ["10.103.8.0/24"]
        }
      }
      egress = {
        all = {
          type        = "egress"
          port        = 0
          protocol    = "-1"
          protocl     = "tcp"
          cidr_blocks = ["10.103.8.0/24"]
        }
        https = {
          description = "HTTPS traffic from ecs services"
          type        = "egress"
          port        = 443
          protocol    = "tcp"
          cidr_blocks = ["0.0.0.0/0"]
        }
         efs = {
          description           = "workbench to efs mount points"
          type                  = "egress"
          port                  = 2049
          protocol              = "tcp"
          //source_security_group = aws_security_group.this["efs_mount_sg"].id
          cidr_blocks = ["10.103.8.0/24"]
        }
      }
    }
  }


  security_group_rules_flat = flatten([
    for rule_key, rule_value in local.security_groups : [
      for rule_type_key, rule_type_attr in rule_value : [
        for rule, rule_attr in rule_type_attr : {
          security_group            = rule_key
          protocol                  = rule_attr.protocol
          port                      = try(rule_attr.port, null)
          from_port                 = try(rule_attr.from_port, null)
          to_port                   = try(rule_attr.to_port, null)
          type                      = rule_type_key
          name                      = rule
          description               = try(rule_attr.description, null)
          cidr_blocks               = try(rule_attr.cidr_blocks, null)
          source_security_group_key = try(rule_attr.source_security_group_key, null)
        }
      ]
    ]
  ])
  security_group_rules = { for rule in local.security_group_rules_flat : "${rule.security_group}.${rule.type}.${rule.name}" => rule }
}

安全组在 sg.tf 文件中定义如下:

resource "aws_security_group" "this" {
  for_each = local.security_groups

  name        = "${var.cluster_name}/${each.key}"
  description = "Security group for ${var.cluster_name}/${each.key}"
  vpc_id      = var.vpc_id_prod
  tags        = merge(var.tags, { Name = "${var.cluster_name}/${each.key}" })
}

resource "aws_security_group_rule" "this" {
  for_each = local.security_group_rules

  security_group_id        = aws_security_group.this[each.value.security_group].id
  description              = try(each.value.description, null)
  type                     = each.value.type
  from_port                = coalesce(each.value.port, each.value.from_port)
  to_port                  = coalesce(each.value.port, each.value.to_port)
  protocol                 = each.value.protocol
  cidr_blocks              = try(each.value.cidr_blocks, null)
  source_security_group_id = try(coalesce(each.value.source_security_group_id, aws_security_group.this[each.value.source_security_group_key].id), null)
}

terraform 验证生成以下错误,如主题中所述:

错误:循环:aws_security_group.this、local.security_groups(展开)

依赖循环的原因是因为你的aws_security_group.this依赖于local.security_groups,而你的嵌套local.security_groups.ALB_Internal_rules_workbench_prod.egress.all.source_security_group_rule导致了对aws_security_group.this的依赖。不幸的是,您无法通过更改为 for_each = toset(keys(local.security_groups)).

来避免这种情况

您需要通过将来自 local.security_groups 的安全组名称与来自 local.security_groups 的安全组规则分离来解决此问题。名称需要是 setlist 转换为 set,并且安全组规则可以保留在上面的结构中。例如:

locals {
  security_group_names = toset(["ALB_Internal_rules_workbench_prod", "workbench_service"])
}

然后:

resource "aws_security_group" "this" {
  for_each = local.security_group_names
  ...
}