You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform aws_security_group如何通过变量传入ingress和egress规则块

解决方案

1. 重构变量定义,使用可选对象属性

基于Terraform 1.3及以上版本稳定支持的optional类型约束,你可以直接在变量声明中标记可选字段并设置默认值,无需手动在传参时合并默认配置:

# variables.tf
variable "sg_ingress" {
  type = list(object({
    from_port        = number
    to_port          = number
    protocol         = string
    cidr_blocks      = optional(list(string), [])
    ipv6_cidr_blocks = optional(list(string), [])
    prefix_list_ids  = optional(list(string), [])
    security_groups  = optional(list(string), [])
    self             = optional(bool, false)
    description      = optional(string, "")
  }))
  default = []
}

variable "sg_egress" {
  type = list(object({
    from_port        = number
    to_port          = number
    protocol         = string
    cidr_blocks      = optional(list(string), [])
    ipv6_cidr_blocks = optional(list(string), [])
    prefix_list_ids  = optional(list(string), [])
    security_groups  = optional(list(string), [])
    self             = optional(bool, false)
    description      = optional(string, "")
  }))
  default = []
}

只有from_port、to_port、protocol是必填字段,其余字段未传值时会自动使用声明的默认值。

2. 用动态块生成安全组规则

直接通过dynamic块遍历传入的规则列表生成对应的ingress/egress块,空值参数会被AWS provider自动忽略,不需要额外处理:

# main.tf
resource "aws_security_group" "sg" {
  name   = "Example security group"
  vpc_id = var.vpc_id

  dynamic "ingress" {
    for_each = var.sg_ingress
    content {
      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
      prefix_list_ids  = ingress.value.prefix_list_ids
      security_groups  = ingress.value.security_groups
      self             = ingress.value.self
      description      = ingress.value.description
    }
  }

  dynamic "egress" {
    for_each = var.sg_egress
    content {
      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
      prefix_list_ids  = egress.value.prefix_list_ids
      security_groups  = egress.value.security_groups
      self             = egress.value.self
      description      = egress.value.description
    }
  }
}

3. 简化传参逻辑

现在不需要手动合并默认值,直接按需求传入对应字段即可:

# terragrunt.hcl
locals {
  some_sg_id = "sg-123abc456"
}

inputs = {
  sg_egress = [
    {
      from_port   = 123
      to_port     = 123
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    },
    {
      from_port       = 53
      to_port         = 53
      protocol        = "tcp"
      security_groups = [local.some_sg_id]
    }
  ]

  sg_ingress = [
    {
      from_port   = 22
      to_port     = 22
      protocol    = "tcp"
      cidr_blocks = ["10.0.0.0/8"]
    }
  ]
}

方案优势

  • 移除了冗余的默认值合并逻辑,传参更简洁
  • 保留了完整的类型校验能力,不会丢失类型安全
  • 自动适配所有可选规则参数,无需针对不同规则做特殊处理
  • 符合Terraform官方推荐的动态块使用范式

内容的提问来源于stack exchange,提问作者Jack Pettersson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 18:36:01