我正在考虑创建一个模块,为随后调用的所有模块设置顶级上下文(一堆共享常量)。为了使每个模块不必创建上下文模块的模块对象,我希望入门级模块创建该对象并将其作为输入变量传递给所有其他模块。
我有这个代码并且它有效:
├── main.tf
├── modules
│ ├── mod1
│ │ └── mod1.tf
│ ├── mod2
│ │ └── mod2.tf
main.tf:
module mod1 {
source = "./modules/mod1"
var1 = "hello"
var2 = "world"
}
module mod2 {
source = "./modules/mod2"
var1 = module.mod1
}
output "mod1" {
value = module.mod1
}
output "mod2" {
value = module.mod2
}
模块/mod1/mod1.tf:
variable "var1" {
type = string
}
variable "var2" {
type = string
}
output "out1" {
value = "In module1; got var1 = ${var.var1}"
}
output "out2" {
value = "In module1; got var2 = ${var.var2}"
}
模块/mod2/mod2.tf:
variable "var1" {
type = any
}
output "out1" {
value = "var1 is ${var.var1.out1}, var2 is ${var.var1.out2}"
}
跑步时
$ terraform init && terraform plan
我明白了
Changes to Outputs:
+ mod1 = {
+ out1 = "In module1; got var1 = hello"
+ out2 = "In module1; got var2 = world"
}
+ mod2 = {
+ out1 = "var1 is In module1; got var1 = hello, var2 is In module1; got var2 = world"
}
通常这样做吗?如果不是,这种方法是否存在任何风险,例如 Terraform 在未来版本中不支持该功能?
引用表示模块调用的对象是有效的 Terraform 语法,您可以在任何需要适当类型对象的位置使用该结果。
您在示例中使用了
type = any
,它要求 Terraform 自动推断变量类型。一种更健壮的编写方法是声明您期望的实际对象类型,因此,如果第一个模块以破坏您的假设的方式发生更改,则会产生更好的错误消息:
variable "var1" {
type = object({
out1 = string
out2 = string
})
}
output "out1" {
value = "var1 is ${var.var1.out1}, var2 is ${var.var1.out2}"
}
output "out1"
中的表达式直接引用out1
和out2
属性,因此编写变量可以接受any类型的值是不准确的:如果省略这些属性中的任何一个,此模块将失败.
特殊的
any
类型约束仅适用于您的模块可以接受 字面上任何类型的情况,例如,如果您将变量值传递给像 jsonencode
或 yamlencode
这样允许任何类型的函数。