【问题标题】:Terraform for loop to generate security group rulesTerraform for 循环生成安全组规则
【发布时间】:2021-10-16 03:15:29
【问题描述】:

我正在尝试在 Terraform 中生成安全组规则,以作为入口块馈送到 aws_security_group。我不使用 aws_security_group_rule,因为我希望模块在自源等方面具有灵活性。

将私有子网 cidr_block 和规则描述作为可用区的示例。

简化示例:我实际上是从 Terraform 状态等中提取出来的。

环境

Terraform v1.0.8

来源

地图列表

locals {
  subnets = [
    {
      availability_zone = "us-east-1a"
      cidr_block = "10.0.0.0/23"
    },
    {
      availability_zone = "us-east-1b"
      cidr_block = "10.0.2.0/23"
    },
    {
      availability_zone = "us-east-1c"
      cidr_block = "10.0.4.0/23"
    }
  ]
}

预期结果

地图列表

[
    {
      description               = "us-east-1a"
      type                      = "ingress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = ["10.0.0.0/23"]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    },
    {
      description               = "us-east-1b"
      type                      = "ingress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = ["10.0.2.0/23"]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    },
    {
      description               = "us-east-1c"
      type                      = "ingress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = ["10.0.4.0/23"]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    }
]

无工作草案(此处需要帮助)

ingress_rules = flatten([
    for subnets, values in local.subnets : [
      for key in values: {
        description               = key.availability_zone
        type                      = "ingress"
        from_port                 = "0"
        to_port                   = "0"
        protocol                  = "-1"
        cidr_blocks               = [key.cidr_block]
        ipv6_cidr_blocks          = []
        prefix_list_ids           = []
        security_groups           = []
        self                      = false
      }
    ]
  ])

【问题讨论】:

    标签: amazon-web-services terraform


    【解决方案1】:

    你的for 太多了。应该是:

      ingress_rules = [
        for subnets, values in local.subnets : {
            description               = values.availability_zone
            type                      = "ingress"
            from_port                 = "0"
            to_port                   = "0"
            protocol                  = "-1"
            cidr_blocks               = [values.cidr_block]
            ipv6_cidr_blocks          = []
            prefix_list_ids           = []
            security_groups           = []
            self                      = false
        }
      ] 
    

    【讨论】:

    • 完美,感谢一百万!
    • 糟糕,忘记了。繁荣完成!你让我畅通无阻,然后我以多种不同的模式使用了这个例子。谢谢!
    • @Levon 没问题。很高兴我能帮上忙。
    【解决方案2】:

    AWS 安全组规则生成示例

    基于@Marcin 帮助的其他示例

    VPC 和远程 WAN IP 访问

    access_lists.tfvars

    access_lists = {
      office = {
        hq                    = "102.55.22.34/32"
      },
      remote = {
        first_last            = "12.32.211.243/32"
      }
    }
    

    local.tf

    locals {
      cidr_list_office              = var.access_lists.office
      cidr_list_remote              = var.access_lists.remote
    
      public_access_cidrs           = merge(
        local.cidr_list_office,
        local.cidr_list_remote
      )
    
      ingress_rule_vpc = [
        {
          description               = "vpc - Managed by Terraform"
          type                      = "ingress"
          from_port                 = 0
          to_port                   = 0
          protocol                  = "-1"
          cidr_blocks               = [data.terraform_remote_state.network.outputs.vpc.cidr_block]
          ipv6_cidr_blocks          = []
          prefix_list_ids           = []
          security_groups           = []
          self                      = false
        }
      ]
    
      ingress_rules_public = [
        for desc, cidr in local.public_access_cidrs : {
          description               = "${desc} - Managed by Terraform"
          type                      = "ingress"
          from_port                 = "0"
          to_port                   = "0"
          protocol                  = "-1"
          cidr_blocks               = [cidr]
          ipv6_cidr_blocks          = []
          prefix_list_ids           = []
          security_groups           = []
          self                      = false
        }
      ]
    
      ingress_rules                 = concat(local.ingress_rule_vpc, local.ingress_rules_public)
    }
    

    EFS(2 个选项)

    嵌套的 for_each 调用。可以向 tfvar 添加更多内容,然后在本地设置映射到 egress_rules.xyz/ingress_rules.xyz 的 sg 规则

    efs.tfvars

    efs = {
      jenkins = {
        encrypted                 = "false"
        performance_mode          = "generalPurpose"
        throughput_mode           = "bursting"
        throughput_in_mibps       = "0"
      }
    }
    

    local.tf(选项 1 - 私有子网)

    locals {
      # Allow all Private Subnets
      jenkins_ingress_rules = [
        for subnets, values in data.terraform_remote_state.network.outputs.subnets.private : {
          description               = values.availability_zone
          type                      = "ingress"
          from_port                 = "0"
          to_port                   = "0"
          protocol                  = "-1"
          cidr_blocks               = [values.cidr_block]
          ipv6_cidr_blocks          = []
          prefix_list_ids           = []
          security_groups           = []
          self                      = false
        }
      ]
    
      # VPC Private Subnets Only
      jenkins_egress_rules = [
        {
          description               = "Managed by Terraform"
          type                      = "egress"
          from_port                 = "0"
          to_port                   = "0"
          protocol                  = "-1"
          cidr_blocks               = ["0.0.0.0/0"]
          ipv6_cidr_blocks          = []
          prefix_list_ids           = []
          security_groups           = []
          self                      = false
        }
      ]
    
      egress_rules = {
        jenkins                     = local.jenkins_egress_rules
      }
    
      ingress_rules = {
        jenkins                     = local.jenkins_ingress_rules
      }
    }
    

    local.tf(选项 2 - 自来源)

    locals {
      # Self sourced security group. Have to be in the SG for access.
      jenkins_ingress_rules = [
        {
          description               = "Managed by Terraform"
          from_port                 = 0
          to_port                   = 0
          protocol                  = "-1"
          self                      = true
          cidr_blocks               = []
          ipv6_cidr_blocks          = []
          prefix_list_ids           = []
          security_groups           = []
        }
      ]
    
      # VPC Private Subnets Only
      jenkins_egress_rules = [
        {
          description               = "Managed by Terraform"
          type                      = "egress"
          from_port                 = "0"
          to_port                   = "0"
          protocol                  = "-1"
          cidr_blocks               = ["0.0.0.0/0"]
          ipv6_cidr_blocks          = []
          prefix_list_ids           = []
          security_groups           = []
          self                      = false
        }
      ]
    
      egress_rules = {
        jenkins                     = local.jenkins_egress_rules
      }
    
      ingress_rules = {
        jenkins                     = local.jenkins_ingress_rules
      }
    }
    

    main.tf

    module "security_groups" {
      for_each                      = var.efs
      base_aws_tags                 = module.aws_tags.aws_tags
      name_suffix                   = "efs-${each.key}"
      egress_rules                  = lookup(local.egress_rules, each.key)
      ingress_rules                 = lookup(local.ingress_rules, each.key)
      source                        = "../../../modules/security_group"
      vpc                           = data.terraform_remote_state.network.outputs.vpc
    }
    

    希望能帮助其他人! -=莱文

    【讨论】:

      猜你喜欢
      • 2021-08-10
      • 2019-07-28
      • 2021-10-20
      • 2020-10-06
      • 1970-01-01
      • 2022-06-30
      • 1970-01-01
      • 1970-01-01
      • 2021-03-06
      相关资源
      最近更新 更多