可以使用字符串和地图元素的 Terraform 地图吗?

red*_*888 16 terraform

我想创建一个这样的地图:

variable "test" {
  type = map(any)
  default = {
    param1 = "sdfsdf",
    param2 = "sdfsfd",
    param3 = {
      mylist = [
        "aaaaa",
        "bbbbb",
        "ccccc"
      ]
    }
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

This default value is not compatible with the variable's type constraint: all
map elements must have the same type.
Run Code Online (Sandbox Code Playgroud)

这是否意味着我已经正确定义了 var 或者 Terraform 不允许这样做?

Mar*_*ins 17

您在这里遇到的是 Terraform 语言中集合类型结构类型之间的差异。

“Map”是一种集合类型,映射值是任意数量的元素,每个元素都由任意字符串标识,但所有值都具有相同类型。

在您的情况下,听起来您想声明您需要一组特定的属性,每个属性都有自己的类型约束。每个元素具有单独类型的固定结构由结构类型表示,“对象”是与地图最相似的结构类型类型。

以下是一个对象类型约束,它将接受您在问题中包含的示例值:

variable "test" {
  type = object({
    param1 = string
    param2 = string
    param3 = object({
      mylist = list(string)
    })
  })
}
Run Code Online (Sandbox Code Playgroud)

如果您想允许调用者设置任意数量的键,param3并且它们都将是字符串列表,那么您可以将其设置为字符串列表的映射:

variable "test" {
  type = object({
    param1 = string
    param2 = string
    param3 = map(list(string))
  })
}
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,模块会期望特定的数据类型,并且如果给定值不是该类型,则会失败,在这种情况下,完整写出该类型会很有帮助,以便为调用模块的人员提供指导并允许 Terraform 进行验证价值。然而,在某些情况下,您确实只想接受任何任意值——例如,如果您打算仅对值进行 JSON 编码并将其逐字发送到资源的参数——因此在这种情况下,您可以设置类型约束any,它将接受任何类型的值:

variable "test" {
  type = any
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,Terraform 根本不会检查传入值,因此您的模块不应对其类型做出任何假设。


Mar*_*cin 6

它不起作用,因为您在映射、字符串和字符串列表中混合了类型,如任何文档中所述。

在你的情况下,你可以使用type = any

variable "test" {

  type = any
  
  default = {
    param1 = "sdfsdf",
    param2 = "sdfsfd",
    param3 = {
    mylist = [
       "aaaaa",
       "bbbbb",
       "ccccc"
     ]
   }
  }
}
Run Code Online (Sandbox Code Playgroud)