首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使Terraform用默认值替换空值?

如何使Terraform用默认值替换空值?
EN

Stack Overflow用户
提问于 2021-09-13 15:13:05
回答 3查看 26.9K关注 0票数 14

Terraform文档指出,这种情况应该已经发生:

https://www.terraform.io/docs/language/expressions/types.html

null:表示缺勤或省略的值。如果将资源或模块的参数设置为null,Terraform的行为就好像您完全忽略了它--如果它有参数,它将使用参数的默认值,如果参数是强制的,则会引发错误。

我正在调用一个具有以下变量文件的模块"foo“:

代码语言:javascript
运行
复制
variable "bar" {
  type    = string
  default = "HelloWorld"
}

示例1

当我使用以下代码调用它时:

代码语言:javascript
运行
复制
module "foo" {
  source = "../modules/foo"
  bar = null
}

结果是一个错误。"str“参数的无效值:参数不能为null。在使用bar时触发。

示例2

当我使用以下代码调用它时(省略它,而不是取消它):

代码语言:javascript
运行
复制
module "foo" {
  source = "../modules/foo"
  # bar = null
}

结果就是它起作用了。"bar“变量默认为"HelloWorld”。

这似乎是Terraform中的一个bug,其他人也提出了,但没有解决。https://github.com/hashicorp/terraform/issues/27730

有人知道解决方案或工作吗?

版本信息:

代码语言:javascript
运行
复制
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的评论和一些研究,有一个使用有条件检查的丑陋解决方案:

代码语言:javascript
运行
复制
variable "foo" {
  type    = string
  default = "HelloWorld"
}
locals {
  foo = var.foo == null ? "HelloWorld" : var.foo
}

为什么

我的用例是为了避免重复的代码。我有两个非常相似的模块,一个是另一个的子集。我使用的解决方案是将模块按顺序调用每个模块,即祖父母、父级和子级。

我希望“祖父母”可以使用这些变量,但是如果省略了这些变量,那么“子”下面的模块应该使用默认值来设置它们。"HelloWorld“。但是要在整个家族行中公开这些变量,我必须将它们包括在所有模块中,在高模块(祖父母和父模块)中,我想将它们默认为null,允许它们是可选的,但也使它们在行的更远的“子”中被设置为默认值。

...I认为我需要一个图表。

EN

回答 3

Stack Overflow用户

发布于 2022-02-16 23:56:55

从Terraform1.1.0开始,variable声明现在支持nullable argument。它默认为true,以保留现有行为。但是,任何未指定或设置为nullable=false的变量都将被指定为默认值。

main.tf

代码语言:javascript
运行
复制
variable "nullable" {
  type    = string
  default = "Used default value"
}

output "nullable" {
  value = coalesce(var.nullable, "[null]")
}

variable "non_nullable" {
  type     = string
  default  = "Used default value"
  nullable = false
}

output "non_nullable" {
  value = coalesce(var.non_nullable, "[null]")
}

terraform.tfvars

代码语言:javascript
运行
复制
nullable     = null
non_nullable = null

注意在输出块中使用coalesce。Terraform设置为null的所有输出,因此这确保了任何null值仍然显示在输出中。

应用此配置后,我们可以从运行terraform output中看出,当nullable=true (默认)保持一个显式设置的null值时,对于nullable=false,任何null值都会被忽略以支持default

代码语言:javascript
运行
复制
# terraform output
non_nullable = "Used default value"
nullable = "[null]"
票数 13
EN

Stack Overflow用户

发布于 2021-12-05 23:06:07

这是针对较早版本的Terraform

如果使用Terraform1.1.x或更高版本,并且不需要支持较早版本的Terraform,则使用nullable方法

可以将默认值设置为null,并通过coalesce函数在local中设置实际默认值。

使用尝试

  • 这适用于空空字符串

代码语言:javascript
运行
复制
variable "foo" {
  type    = string
  default = null
}

locals {
  # return var.foo if it's not null
  # return "HelloWorld" if var.foo is null
  foo = try(length(var.foo), 0) > 0 ? var.foo : "HelloWorld"
}

output "foo" {
  value = local.foo
}

使用聚结

  • 这只适用于空字符串,而不是空字符串

代码语言:javascript
运行
复制
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_coalesce, "HelloWorld")
}

output "foo" {
  value = local.foo
}

使用默认值null返回HelloWorld

代码语言:javascript
运行
复制
$ terraform apply -auto-approve

...

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

foo = "HelloWorld"

使用新值将否定local中的默认设置。

代码语言:javascript
运行
复制
$ terraform apply -auto-approve -var="foo=HelloUniverse"

...

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

foo = "HelloUniverse"
票数 8
EN

Stack Overflow用户

发布于 2022-10-05 15:43:28

我希望contains()与条件的结合可以解决这个问题(terraform版本> 1.xx)

基于这种组合,我可以解决一个for_each解决方案。在下面的示例中,.value部件包含一组属性。有点懒散地尝试这个问题;),但这可能有帮助。

代码语言:javascript
运行
复制
your_target_attr = contains(keys(each.value), "your_possible_attribute_value") ? each.value.your_possible_attribute_value : var.your_default_value
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69165146

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档