AWS 安全组的 Terraform 中的变量值

dar*_*ght 5 amazon-web-services terraform terraform-provider-aws

我是 terraform 的新手,正在尝试创建一个具有入口和出口规则的 AWS 安全组。我尝试使用 terraformlookup函数,而不是对值进行硬编码并创建多个入口和出口块。

main.tf文件看起来像这样:

provider "aws" {
  version                 = "~> 2.0"
  region                  = var.region
  profile                 = var.profile
}

resource "aws_security_group" "this" {
  name = "test-sg"
  description = "test security group"

  dynamic "ingress" {
    for_each = var.ingress_rules
    content {
      description      = lookup(ingress.value, "description", null)
      from_port        = lookup(ingress.value, "from_port", null)
      to_port          = lookup(ingress.value, "to_port", null)
      protocol         = lookup(ingress.value, "protocol", null)
      cidr_blocks      = lookup(ingress.value, "cidr_blocks", null)
    }
  }

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

  tags = {
    Name = "test-sg"
  }
}
Run Code Online (Sandbox Code Playgroud)

variables.tf文件看起来像这样

variable "ingress_rules" {
  default     = {
    "description" = ["For HTTP", "For SSH"]
    "from_port"   = ["80", "22"]
    "to_port"     = ["80", "22"]
    "protocol"    = ["tcp", "tcp"]
    "cidr_blocks" = ["0.0.0.0/0", "0.0.0.0/0"]
  }
  type        = map(list(string))
  description = "Security group rules"
}
Run Code Online (Sandbox Code Playgroud)

当我运行时,terraform validate它显示配置有效,但是当我运行时terraform plan,它显示以下错误:

 ingress.value is list of string with 2 elements
 
 Invalid value for "inputMap" parameter: lookup() requires a map as the first
 argument.
Run Code Online (Sandbox Code Playgroud)

花了很长时间仍然无法弄清楚如何解决这个错误。variables.tf将查找值传递到文件的正确方法是什么?

Mat*_*ard 4

您已将变量的默认值构造为带有字符串键和字符串值列表的五个映射。您可能需要一个包含一系列与入口规则的各种属性相关联的键和值的映射。您可以相应地更新变量值,例如:

variable "ingress_rules" {
  default     = {
    "my ingress rule" = {
      "description" = "For HTTP"
      "from_port"   = "80"
      "to_port"     = "80"
      "protocol"    = "tcp"
      "cidr_blocks" = ["0.0.0.0/0"]
    },
    "my other ingress rule" = {
      "description" = "For SSH"
      "from_port"   = "22"
      "to_port"     = "22"
      "protocol"    = "tcp"
      "cidr_blocks" = ["0.0.0.0/0"]
    }
  }
  type        = map(any)
  description = "Security group rules"
}
Run Code Online (Sandbox Code Playgroud)

现在,在for_each迭代器中,第一个值ingress.key将是my ingress rule,第一个值ingress.value将是键和字符串的整个映射。以前,第一个值ingress.keydescription,第一个值是["For HTTP", "For SSH"]。这就是您收到该错误的原因:您无法description从 列表中查找带有键的值["For HTTP", "For SSH"]。更新此变量值后,您应该获得预期的行为。

请注意,您可以使用对象进一步细化您的类型:

default = {
  "my ingress rule" = {
    description = "For HTTP"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  },
  "my other ingress rule" = {
    description = "For SSH"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
type = map(object({
  description = string
  from_port   = number
  to_port     = number
  protocol    = string
  cidr_blocks = list(string)
}))
Run Code Online (Sandbox Code Playgroud)