获取Terraform中变量的类型
有没有办法检测地形中变量的类型?比如说,我有一个获取Terraform中变量的类型,terraform,Terraform,有没有办法检测地形中变量的类型?比如说,我有一个any类型的模块输入变量,我可以根据类型进行某种切换吗 variable "details" { type = any } local { name = var.details.type == map ? var.details["name"] : var.details } 我想归档的是,能够以简写形式传递字符串,或者传递带有附加键的复杂对象 module "foo" { details = "my-name" } 或 我知
any
类型的模块输入变量,我可以根据类型进行某种切换吗
variable "details" {
type = any
}
local {
name = var.details.type == map ? var.details["name"] : var.details
}
我想归档的是,能够以简写形式传递字符串,或者传递带有附加键的复杂对象
module "foo" {
details = "my-name"
}
或
我知道这个例子没有多大意义,您想建议改为使用两个带有默认值的输入变量。此示例仅简化为最小(非)工作示例。最终目标是有一个IAM策略语句列表,因此它将是一个对象列表。Terraform v0.12.20引入了一个新函数,可用于在不同的检索值方法之间进行简单选择,采用不会产生错误的第一种方法
variable "person" {
type = any
# Optional: add a validation rule to catch invalid types,
# though this feature remains experimental in Terraform v0.12.20.
# (Since this is experimental at the time of writing, it might
# see breaking changes before final release.)
validation {
# If var.person.name succeeds then var.person is an object
# which has at least the "name" attribute.
condition = can(var.person.name) || can(tostring(var.person))
error_message = "The \"person\" argument must either be a person object or a string giving a person's name."
}
}
locals {
person = try(
# The value of the first successful expression will be taken.
{name = tostring(var.person)}, # If the value is just a string
var.person, # If the value is not a string (directly an object)
)
}
然后,您可以在配置的其他位置写入local.person.name
以获取名称,而不管调用方传递的是对象还是字符串
此答案的其余部分是早期的响应,现在仅适用于v0.12.0和v0.12.20之间的地形版本 在Terraform中没有基于类型切换行为的机制。一般来说,Terraform倾向于选择特定的类型,这样模块调用者总是一致的,Terraform可以完全验证给定的值,即使这意味着在更简单的情况下会有一点额外的冗长 我建议将
details
定义为一个对象,并让调用者使用name
属性显式写出对象,以便更加明确和一致:
variable "details" {
type = object({
name = string
})
}
如果您需要支持两种不同的类型,Terraform语言中最接近的事情就是定义两个变量并检测哪个是null
:
variable "details" {
type = object({
name = string
})
default = null
}
variable "name" {
type = string
default = null
}
local {
name = var.name != null ? var.name : var.details.name
}
但是,由于目前还没有一种方法来表示必须指定这两个模块中的一个,因此您编写的模块配置必须准备好处理这两个模块都将被设置(在上面的示例中,
var.name
优先)或两者都不会被设置的可能性(在上面的示例中,表达式将产生一个错误,但不是一个非常方便调用方的错误).虽然这种可变模板/鸭子类型目前在Terraform中不可用,但这看起来确实是一个有趣的功能请求。我创建了一个功能请求:-如果得到积极反馈,我将研究实现。谢谢Martin,是的,详细的定义就是我现在拥有的。这很不幸,因为我会有数百个这样的条目,在大多数情况下,一个字符串就足够了。只有很少的条目需要额外的信息。正如fineprint中提到的,它实际上是一个对象/字符串列表。因此理想情况下,一个列表只需定义为x=[“a”,“b”,“c”]
,而不是x=[{name=“a”},{name=“b”},{name=“c”}
。但我知道,不幸的是,现在不可能。
module "example" {
source = "./modules/example"
details = { name = "example" }
}
variable "details" {
type = object({
name = string
})
default = null
}
variable "name" {
type = string
default = null
}
local {
name = var.name != null ? var.name : var.details.name
}