繁体   English   中英

在 Terraform 嵌套循环中创建 AWS 安全组

[英]Creating AWS Security Groups in a Terraform Nested Loop

使用 Terraform 版本 12,我正在尝试创建一些 AWS 安全组规则。 我需要创建 x 条规则,这些规则可能与端口不同。 需要为从 sg_groups 数据查找返回的每个安全组创建这些规则。 所以我有一个嵌套列表/地图。 我认为使用 Terraform 的 for_each 和 for 循环 function 是可行的,但我正在努力思考如何使这项工作发挥作用。 任何人都可以帮助我获得正确的循环语法。 注意:sg_rules map 的格式不是一成不变的,可以采用任何最有效的方式进行格式化。

variable "sg_rules" = {
    type = map
    default = {
        80 = {
            protocol                  = "tcp"
            from_port                 = 80
            to_port                   = 80
        },
        443 = {
            protocol                  = "tcp"
            from_port                 = 443
            to_port                   = 443
        },
        service_ports = {
            protocol                  = "tcp"
            from_port                 = 60000
            to_port                   = 60500
        }
    }
}

data "aws_security_groups" "sg_groups" {
  filter {
    name   = "group-name"
    values = var.sg_names
  }
}

以典型的方式,一旦我寻求帮助,我最终会自己弄清楚,或者至少是一种方法。 以上是我的想法,如果大家有更好的想法欢迎留言

variable "sg_rules" = {
    type = map
    default = [
       {
            protocol                  = "tcp"
            from_port                 = 80
            to_port                   = 80
        },
        {
            protocol                  = "tcp"
            from_port                 = 443
            to_port                   = 443
        },
        {
            protocol                  = "tcp"
            from_port                 = 60000
            to_port                   = 60500
        }
    }
}

locals {
  gw_to_mx_rules = [
    for pair in setproduct(data.aws_security_groups.sg_groups.ids, var.sg_rules) : {
      sg          = pair[0]
      type        = pair[1].type
      protocol    = pair[1].protocol
      from_port   = pair[1].from_port
      to_port     = pair[1].to_port
    }
  ]
}

data "aws_security_groups" "sg_groups" {
  filter {
    name   = "group-name"
    values = var.sg_names
  }
}

resource "aws_security_group_rule" "gw_to_mx" {
  for_each = { for rule in local.gw_to_mx_rules : "${rule.type}.${rule.from_port}.${rule.to_port}.${rule.protocol}.${rule.sg}" => rule }
  description                = "MX Communication"
  type                       = each.value.type
  from_port                  = each.value.from_port
  to_port                    = each.value.to_port
  protocol                   = each.value.protocol
  source_security_group_id   = each.value.sg
  security_group_id          = aws_security_group.waf_instance_sg.id
}

下面是一个示例,其中我使用嵌套的 for_each 创建了 AWS 安全组列表。 一个 for_each 用于创建 AWS 安全组列表,另一个用于创建动态入口和出口规则。

主程序

resource "aws_security_group" "security-groups" {
  # Dynamic number of Security Groups 
  for_each = var.security_group_configurations.security_groups
  name        = each.value.name
  description = each.value.description
  vpc_id      = var.vpc_id

  # Dynamic number of Ingress Rules
  dynamic ingress {
    for_each = var.security_group_configurations.security_groups[each.key].ingress_rules
    content {
      description      = ingress.value.description
      from_port        = ingress.value.from_port
      to_port          = ingress.value.to_port
      protocol         = ingress.value.protocol
      cidr_blocks      = ingress.value.cidr_blocks
      ipv6_cidr_blocks = ingress.value.ipv6_cidr_blocks
    }
    
  }

  # Dynamic number of Egress Rules
  dynamic egress {
    for_each = var.security_group_configurations.security_groups[each.key].egress_rules
    content {
      description      = egress.value.description  #Here the 'egress' is the dynamic egress block
      from_port        = egress.value.from_port
      to_port          = egress.value.to_port
      protocol         = egress.value.protocol
      cidr_blocks      = egress.value.cidr_blocks
      ipv6_cidr_blocks = egress.value.ipv6_cidr_blocks
    }
  }

  tags = each.value.tags
}

变量.tf

variable "security_group_configurations" {
    description = "All Security_Groups related configuration"
}

variable "vpc_id" {
    description = "Vpc Id for security_groups"
}

例子.tfvars

vpc_id = "vpc-0be6071d37dsd985b"


    
security_group_configurations = {
    security_groups = {
#--------------------->>  Security Group 0  <-------------------------------------------
        "0" = { 
            name        = "security_group_0"
            description = "security_group_0"
            # Ingress Rules
            ingress_rules = {
                # Ingress Rule 0
                0 = {
                    description      = "TLS from Public Internet"
                    from_port        = 443
                    to_port          = 443
                    protocol         = "tcp"
                    cidr_blocks      = ["0.0.0.0/0"]
                    ipv6_cidr_blocks = ["::/0"]
                },
                # Ingress Rule 1
                1 = {
                    description      = "SSH from Public Internet"
                    from_port        = 22
                    to_port          = 22
                    protocol         = "tcp"
                    cidr_blocks      = ["0.0.0.0/0"]
                    ipv6_cidr_blocks = ["::/0"]
                },
            }
            # Egress Rules
            egress_rules =  {
                # Egress Rule 0
                0 = {
                    description      = "Allow all traffic to outside"
                    from_port        = 0
                    to_port          = 0
                    protocol         = "-1"
                    cidr_blocks      = ["0.0.0.0/0"]
                    ipv6_cidr_blocks = ["::/0"]
                },
                # Egress Rule 1
                ##############
            }
            # Tags for Security Group 0
            tags = {
                Name = "security_group_0"
            } 
        },
#--------------------->>  Security Group 1  <-------------------------------------------
        "1" = { 
            name        = "security_group_1"
            description = "security_group_1"
            # Ingress Rules
            ingress_rules = {
                # Ingress Rule 0
                0 = {
                    description      = "TLS from Public Internet"
                    from_port        = 443
                    to_port          = 443
                    protocol         = "tcp"
                    cidr_blocks      = ["0.0.0.0/0"]
                    ipv6_cidr_blocks = ["::/0"]
                },
                # Ingress Rule 1
                1 = {
                    description      = "SSH from Public Internet"
                    from_port        = 22
                    to_port          = 22
                    protocol         = "tcp"
                    cidr_blocks      = ["0.0.0.0/0"]
                    ipv6_cidr_blocks = ["::/0"]
                },
            }
            # Egress Rules
            egress_rules =  {
                # Egress Rule 0
                0 = {
                    description      = "Allow all traffic to outside"
                    from_port        = 0
                    to_port          = 0
                    protocol         = "-1"
                    cidr_blocks      = ["0.0.0.0/0"]
                    ipv6_cidr_blocks = ["::/0"]
                },
                # Egress Rule 1
                ####
                ####
            }
            # Tags for Security Group 1
            tags = {
                Name = "security_group_1"
            }
        }
#--------------------->>  Security Group 2  <-------------------------------------------
#######
#######
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM