terraform - 如何让 Terraform 用默认值替换空值?
问题描述
Terraform 文档表明这应该已经发生了:
https://www.terraform.io/docs/language/expressions/types.html
null:代表缺席或遗漏的值。如果您将资源或模块的参数设置为 null,Terraform 的行为就好像您完全省略了它一样 - 如果参数有默认值,它将使用该参数的默认值,如果该参数是强制性的,则会引发错误。
我正在调用具有以下变量文件的模块“foo”:
variable "bar" {
type = string
default = "HelloWorld"
}
示例 1
当我使用此代码调用它时:
module "foo" {
source = "../modules/foo"
bar = null
}
结果是一个错误。“str”参数的值无效:参数不能为空。使用 bar 时触发。
示例 2
当我使用此代码调用它时(省略它,而不是将它归零):
module "foo" {
source = "../modules/foo"
# bar = null
}
结果是它起作用了。“bar”变量默认为“HelloWorld”。
这似乎是 Terraform 中的一个错误,其他人也提出了但没有解决。 https://github.com/hashicorp/terraform/issues/27730
有谁知道解决方案或解决方法?
版本信息:
Terraform v1.0.5
on linux_amd64
+ provider registry.terraform.io/hashicorp/google v3.51.0
+ provider registry.terraform.io/hashicorp/null v3.1.0
+ provider registry.terraform.io/hashicorp/random v3.1.0
+ provider registry.terraform.io/hashicorp/time v0.7.2
解决方法
根据@Matt Schuchard 的评论和一些研究,使用条件检查有一个丑陋的解决方案:
variable "foo" {
type = string
default = "HelloWorld"
}
locals {
foo = var.foo == null ? "HelloWorld" : var.foo
}
为什么
我的用例是试图避免重复代码。我有 2 个非常相似的模块,一个是另一个的子集。我正在使用的解决方案是将模块按顺序调用每个模块,即祖父母、父母和孩子。
我想让“祖父母”可以使用这些变量,但如果它们被省略,那么“子”下面的模块应该使用默认值设置它们,例如“HelloWorld”。但是要在整个家族中一直暴露这些变量,我必须将它们包含在所有模块和高级模块(祖父母和父母)中,我想将它们默认为空,允许它们是可选的,但仍然使它们成为在“子”中设置为默认值。
...我想我需要一个图表。
解决方案
您可以通过函数将默认值设置为null
并设置真正的默认值local
coalesce
variable "foo" {
type = string
default = null
}
locals {
# return var.foo if it's not null
# return "HelloWorld" if var.foo is null
foo = coalesce(var.foo, "HelloWorld")
}
output "foo" {
value = local.foo
}
null
使用return的默认值HelloWorld
$ terraform apply -auto-approve
...
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
foo = "HelloWorld"
使用新值会否定local
$ terraform apply -auto-approve -var="foo=HelloUniverse"
...
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
foo = "HelloUniverse"
推荐阅读
- ios - 如何访问 ubiquitousItemDownloadingStatus 资源值的值?
- html - 如何在 ng-repeat 中使用嵌套子级中的变量?
- jmeter - JMeter在使用调度程序时忽略持续时间
- database - 在 ms-access 中设置 Recordsource 之前设置过滤器?
- android-studio - Android Studio 3.2 gradle 同步按钮不见了
- linkedin - LinkedIn API:获取访问令牌时拒绝访问
- spring-boot - springboot websocket不起作用@Autowired
- php - PHP Mailchimp v3
- javascript - res.render sweetalert 在 ejs 文件上
- blockchain - Solidity: Error when calling a function of another contract. Error: The constructor should be payable when you send value