有没有办法检测 Terraform 中变量的类型?比如说,我有一个类型为 的模块输入变量any,我可以根据类型进行某种切换吗?
variable "details" {
type = any
}
local {
name = var.details.type == map ? var.details["name"] : var.details
}
Run Code Online (Sandbox Code Playgroud)
我想要归档的是,能够传递字符串作为速记或带有附加键的复杂对象。
module "foo" {
details = "my-name"
}
Run Code Online (Sandbox Code Playgroud)
或者
module "foo" {
details = {
name = "my-name"
age = "40"
}
}
Run Code Online (Sandbox Code Playgroud)
我知道这个例子没有多大意义,您想建议使用两个带有默认值的输入变量。该示例只是简化为最小(非)工作示例。最终目标是拥有一个 IAM 策略语句列表,因此它将是一个对象列表的列表。
Terraform v0.12.20 引入了一个新函数try,可用于在检索值的不同方式之间进行简洁选择,采用第一个不会产生错误的方式。
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)
)
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以在配置的其他位置编写local.person.name以获取名称,无论调用者传递的是对象还是字符串。
此答案的其余部分是早期的响应,现在仅适用于 v0.12.0 和 v0.12.20 之间的 Terraform 版本。
Terraform 中没有基于类型切换行为的机制。一般来说,Terraform 倾向于选择特定类型,以便模块调用者始终保持一致,并且 Terraform 可以完全验证给定的值,即使这意味着在更简单的情况下会有点额外的冗长。
我建议只定义details为一个对象,并让调用者使用该属性显式写出该对象name,以便更加明确和一致:
variable "details" {
type = object({
name = string
})
}
Run Code Online (Sandbox Code Playgroud)
module "example" {
source = "./modules/example"
details = { name = "example" }
}
Run Code Online (Sandbox Code Playgroud)
如果您需要支持两种不同的类型,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
}
Run Code Online (Sandbox Code Playgroud)
然而,由于目前没有一种方法来表达必须指定这两者之一,因此您编写的模块配置必须准备好处理两者都被设置的可能性(在上面的示例中,var.name优先)或者两者都不被设置将被设置(在上面的示例中,表达式会产生错误,但不是一个非常适合调用者的错误)。
terraform v1.0+ 为此引入了一个新函数 type()。请参阅https://www.terraform.io/language/functions/type
| 归档时间: |
|
| 查看次数: |
13901 次 |
| 最近记录: |