amazon-web-services - Terraform 因无效的 for_each 参数而失败/给定的 "for_each"参数值不合适

标签 amazon-web-services foreach terraform

运行时terraform planterraform apply提供给 for_each 的列表发生错误说

Error: Invalid for_each argument

  on main.tf line 2, in resource "aws_ssm_parameter" "foo":
  2:   for_each = ["a", "b"]

The given "for_each" argument value is unsuitable: the "for_each" argument
must be a map, or set of strings, and you have provided a value of type tuple.
重现此错误的最小示例如下:
resource "aws_ssm_parameter" "foo" {
  for_each = ["a", "b"]

  name  = "foo-${each.value}"
  type  = "String"
  value = "bar-${each.value}"
}

最佳答案

解释
此错误通常是由将列表传递给 for_each 引起的。 , 但是 for_each仅适用于无序数据类型,即集合和映射。
解决方案
分辨率视情况而定。
字符串列表
如果列表只是字符串列表,最简单的解决方法是添加 toset() -call 将列表转换为可以由 for_each 处理的集合,如下所示

resource "aws_ssm_parameter" "foo" {
  for_each = toset(["a", "b"])

  name  = "foo-${each.value}"
  type  = "String"
  value = "bar-${each.value}"
}
可以重新排列为 map 的列表
如果输入是一个列表,但很容易重新排列为 map ,这通常是最好的方法。
假设我们有一个这样的列表
locals {
  animals = [
    {
      name = "Bello"
      age = 3
      type = "dog"
    },
    {
      name = "Minga"
      age = 4
      type = "cat"
    },
  ]
}
那么适当的重组可能是这样
locals {
  animals = {
    Bello : {
      age = 3
      type = "dog"
    },
    Minga : {
      age = 4
      type = "cat"
    }
  }
}
然后允许您定义
resource "aws_ssm_parameter" "foo" {
  for_each = local.animals

  name  = each.key
  type  = string
  value = "This is a ${each.value.type}, ${each.value.age} years old."
}
不想重新排列的列表
有时有一个列表是很自然的,例如来自不受控制的模块的输出或来自用 count 定义的资源.在这种情况下,可以像这样使用 count
resource "aws_ssm_parameter" "foo" {
  count = length(local.my_list)

  name  = my_list[count.index].name
  type  = "String"
  value = my_list[count.index].value
}
它适用于包含名称和值作为键的映射列表。但是,通常情况下,将列表转换为 map 更合适,而不是像这样
resource "aws_ssm_parameter" "foo" {
  for_each = { for x in local.my_list: x.id => x }

  name  = each.value.name
  type  = "String"
  value = each.value.value
}
这里应该选择任何合适的东西来代替x.id。 .如果 my_list是一个对象列表,通常有一些常见的字段,如名称或键,可以使用。这种方法的优点有利于使用 count如上所述,这是在从列表中插入或删除元素时表现得更好。 count不会注意到插入或删除,因此将更新插入发生位置之后的所有资源,而 for_each实际上只添加或删除具有新的或删除的 id 的资源。

关于amazon-web-services - Terraform 因无效的 for_each 参数而失败/给定的 "for_each"参数值不合适,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62264013/

相关文章:

azure - 在 Azure 上创建资源的服务主体

amazon-web-services - Terraform:将 SEARCH 表达式与 CloudWatch 警报结合使用

linux - Amazon EC2 - MindTerm 身份验证失败,权限被拒绝

amazon-web-services - Googlebot 和 AWS Cloudfront/S3 - 收到一堆 403

powershell - 使用 AWS Powershell 部署到 AWS elastic beanstalk

mysql - 按 unix 时间戳的 Hive 动态分区

php - 在一个 foreach 循环中迭代 3 个表中的每一行 - PHP - Laravel

c# - 如何创建动态 lambda 来使用它?

C# SkipWhile(Item => Item == null) 仍然返回空项目

google-cloud-platform - 可以通过 Terraform 为 Cloud Function 设置 secret 吗?