0

我的主要目标是从 terraforms 模块中的 aws_security_group 资源中删除硬编码的入口和出口配置块。相反,我想传入一个入口和一个出口输入变量,其中包含所有入口和出口规则。

当前 aws_security_group 创建:

# main.tf

resource "aws_security_group" "sg" {

  name = "Example security group"

  egress {
    from_port       = 123
    to_port         = 123
    protocol        = "tcp"
    cidr_blocks     = ["0.0.0.0/0"]
  }
  
  egress {
    from_port       = 53
    to_port         = 53
    protocol        = "tcp"
    security_groups = [local.some_sg_id]
  }
  
  ingress {
    from_port       = 22
    to_port         = 22
    protocol        = "tcp"
    cidr_blocks     = ["10.0.0.0/8"]
  }

  vpc_id = var.vpc_id
}

我想做的事:

# main.tf

resource "aws_security_group" "sg" {

  name = "Example security group"

  egress = var.sg_egress
  ingress = var.sg_ingress

  vpc_id = var.vpc_id
}

问题是入口和出口块具有可选参数。IE 在一个入口语句上我指定了“cidr_blocks”和一个“security_groups”。这使得为​​这些块创建变量语句变得困难。

我已经设法让它使用这个:

# terragrunt.hcl
# Note: we use terragrunt, but in the example below think of this as terraform.tfvars

locals {
  some_sg_id = "sg-123abc456"

  sg_defaults = {
    "security_groups"  = []
    "cidr_blocks"      = []
    "ipv6_cidr_blocks" = []
    "prefix_list_ids"  = []
    "self"             = false
    "description"      = ""
  }
}

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

  sg_ingress [
    merge(local.sg_defaults, {
      from_port       = 123
      to_port         = 123
      protocol        = "tcp"
      cidr_blocks     = ["0.0.0.0/0"]
    })
  ]
}
# variables.tf

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

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

在这里,我为可选属性创建默认(空)值,然后将它们与输入变量中的值合并。这将创建填充了所有属性的输入变量,如果未指定则为空值。这样我就可以创建一个指定所有值的变量语句,但这不是一个非常漂亮的解决方案......

可能可以使用动态块来完成此操作,但到目前为止,我平滑的大脑还无法使其与这些块一起使用。

我见过这个类似的 StackOverflow 问题,但它没有使用可选属性。

4

0 回答 0