如何在 for_each 循环中指定字符串列表?

How to specify list of string within for_each loop?

我正在尝试使用 for_each 创建可重用的安全组及其规则。通过 cidr_blocks = list(string) 时,出现以下错误。如果我删除 cidr_blocks 代码工作正常

╷
│ Error: Invalid index
│
│   on ../../modules/security/main.tf line 18, in resource "aws_security_group" "app_sg":
│   18:       cidr_blocks     = ingress.value["cidr_blocks"]
│     ├────────────────
│     │ ingress.value is object with 3 attributes
│
│ The given key does not identify an element in this collection value.
╵

根模块

###################################
# Create a security group & rules #
###################################

module "application_sg" {
  source        = "../../modules/security"
  create_sg     = var.create_sg
  name_suffix   = var.name_suffix
  sg_name       = var.sg_name
  environment   = local.common-tags.environment
  vpc_id        = one(module.mgt_vpc.vpc_id)
  egress_rules  = var.app_egress_rules
  ingress_rules = var.app_ingress_rules
  cidr_blocks   = var.app_cidr_blocks

  common-tags = local.common-tags
}

module "database_sg" {
  source        = "../../modules/security"
  create_sg     = var.create_sg
  vpc_id        = one(module.sre_vpc.vpc_id)
  sg_name       = var.db_sg_name
  name_suffix   = var.name_suffix
  environment   = local.common-tags.environment
  egress_rules  = var.db_egress_rules
  ingress_rules = var.db_ingress_rules
  ingress_self_sg = true

  common-tags = local.common-tags
}


################################
# List of Security Group Rules #
################################

variable "app_ingress_rules" {
  type = map(object({
    from_port = number
    to_port   = number
    protocol  = string
    cidr_blocks = list(string)
  }))

  default = {
    SSH = {
      from_port = 22
      to_port   = 22
      protocol  = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    },

    HTTP = {
      from_port = 80
      to_port   = 80
      protocol  = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    },

    HTTPS = {
      from_port = 443
      to_port   = 443
      protocol  = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
}


variable "app_egress_rules" {
  type = map(object({
    from_port = number
    to_port   = number
    protocol  = string
    cidr_blocks = list(string)
  }))

  default = {
    ALLOW_ALL = {
      from_port = 0
      to_port   = 0
      protocol  = "-1"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
}


variable "db_ingress_rules" {
  type = map(object({
    from_port = number
    to_port   = number
    protocol  = string
  }))

  default = {
    MYSQL = {
      from_port = 3306
      to_port   = 3306
      protocol  = "tcp"
    },

    HTTPS = {
      from_port = 443
      to_port   = 443
      protocol  = "tcp"
    }
  }
}

variable "db_egress_rules" {
  type = map(object({
    from_port = number
    to_port   = number
    protocol  = string
    cidr_blocks = list(string)
  }))

  default = {
    ALLOW_ALL = {
      from_port = 0
      to_port   = 0
      protocol  = "-1"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
}

子模块

################################
# Create Securiy Group & Rules #
################################

resource "aws_security_group" "app_sg" {
  for_each = var.create_sg ? toset(var.sg_name) : []
  name     = each.key
  vpc_id   = var.vpc_id

  dynamic "ingress" {
    for_each = var.ingress_rules != {} ? toset(values(var.ingress_rules)) : []

    content {
      from_port       = ingress.value["from_port"]
      to_port         = ingress.value["to_port"]
      protocol        = ingress.value["protocol"]
      cidr_blocks     = ingress.value["cidr_blocks"]
      security_groups = var.security_groups
      self            = var.ingress_self_sg
    }
  }

  dynamic "egress" {
    for_each = var.egress_rules != {} ? toset(values(var.egress_rules)) : []

    content {
      from_port       = egress.value["from_port"]
      to_port         = egress.value["to_port"]
      protocol        = egress.value["protocol"]
      cidr_blocks     = egress.value["cidr_blocks"]
      security_groups = var.security_groups
      self            = var.egress_self_sg
    }
  }

  tags = merge(
    var.common-tags,
    {
      "Name" = "${each.key}-${lower(var.environment)}"
    }
  )
}

// Variables

variable "create_sg" {
}

variable "vpc_id" {
}

variable "environment" {
}

variable "name_suffix" {
}

variable "sg_name" {
}

variable "common-tags" {
}

variable "ingress_rules" {
  type    = any
  default = {}
}

variable "egress_rules" {
  type    = any
  default = {}
}

variable "security_groups" {
  type    = list(string)
  default = []
}

variable "ingress_self_sg" {
  type    = bool
  default = false
}

variable "egress_self_sg" {
  type    = bool
  default = false
}

您的 var.db_ingress_rules 没有 cidr_blocks。你必须在那里添加它,例如:


variable "db_ingress_rules" {
  type = map(object({
    from_port = number
    to_port   = number
    protocol  = string
    cidr_blocks = list(string)
  }))

  default = {
    MYSQL = {
      from_port = 3306
      to_port   = 3306
      protocol  = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    },

    HTTPS = {
      from_port = 443
      to_port   = 443
      protocol  = "tcp"
     cidr_blocks = ["0.0.0.0/0"]
    }
  }
}