如何让 Terraform 将空值替换为默认值?

Fre*_*Zey 17 terraform

Terraform 文档表明这应该已经发生:

\n

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

\n
\n

null:表示不存在或遗漏的值。如果您将资源或模块的参数设置为 null,Terraform 的行为就像您完全省略了它 \xe2\x80\x94 它将使用参数的默认值(如果有),或者如果参数有默认值,则会引发错误是强制性的。

\n
\n

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

\n
variable "bar" {\n  type    = string\n  default = "HelloWorld"\n}\n
Run Code Online (Sandbox Code Playgroud)\n

实施例1

\n

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

\n
module "foo" {\n  source = "../modules/foo"\n  bar = null\n}\n
Run Code Online (Sandbox Code Playgroud)\n

结果是一个错误。“str”参数值无效:参数不能为空。当使用 bar 时触发。

\n

实施例2

\n

当我使用此代码调用它时(省略它,而不是将其置空):

\n
module "foo" {\n  source = "../modules/foo"\n  # bar = null\n}\n
Run Code Online (Sandbox Code Playgroud)\n

结果是它有效。“bar”变量默认为“HelloWorld”。

\n

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

\n

有谁知道解决方案或解决方法?

\n

版本信息:

\n
Terraform v1.0.5\non linux_amd64\n+ provider registry.terraform.io/hashicorp/google v3.51.0\n+ provider registry.terraform.io/hashicorp/null v3.1.0\n+ provider registry.terraform.io/hashicorp/random v3.1.0\n+ provider registry.terraform.io/hashicorp/time v0.7.2\n
Run Code Online (Sandbox Code Playgroud)\n

解决方法

\n

根据 @Matt Schuchard 的评论和一些研究,有一个使用条件检查的丑陋解决方案:

\n
variable "foo" {\n  type    = string\n  default = "HelloWorld"\n}\nlocals {\n  foo = var.foo == null ? "HelloWorld" : var.foo\n}\n
Run Code Online (Sandbox Code Playgroud)\n

为什么

\n

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

\n

我想让变量可供“祖父母”使用,但如果它们被省略,那么“孩子”下面的模块应该使用默认值设置它们,例如“HelloWorld”。但是为了在整个家族中暴露这些变量,我必须将它们包含在所有模块和高级模块(祖父母和父母)中,我想将它们默认为空,允许它们是可选的,但仍然导致它们设置为“子”中的默认值。

\n

...我想我需要一张图表。

\n

小智 24

从 Terraform 1.1.0 开始,variable声明现在支持nullable参数。它默认true保留现有行为。但是,任何nullable=false未指定或设置为的null变量都将被分配默认值。

main.tf:

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]")
}
Run Code Online (Sandbox Code Playgroud)

terraform.tfvars

nullable     = null
non_nullable = null
Run Code Online (Sandbox Code Playgroud)

请注意输出coalesce块中的使用。Terraform 会忽略设置为 的任何输出,因此这可确保任何值仍然在输出中显示某些内容。nullnull

应用此配置后,我们可以从运行中看到terraform output,当nullable=true(默认)变量保留显式设置的null值但nullable=false任何null值都会被忽略,以支持default.

# terraform output
non_nullable = "Used default value"
nullable = "[null]"
Run Code Online (Sandbox Code Playgroud)


Som*_*ter 10

这适用于旧版本的 Terraform

nullable如果使用 Terraform 1.1.x 或更高版本并且不需要支持旧版本的 terraform,请使用该方法


您可以通过函数将默认值设置为null并设置真正的默认值localcoalesce

使用尝试

  • 这适用于 null 和空字符串
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
}
Run Code Online (Sandbox Code Playgroud)

使用合并

  • 这只适用于空字符串,不适用于空字符串
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
}
Run Code Online (Sandbox Code Playgroud)

null使用返回值的默认值HelloWorld

$ terraform apply -auto-approve

...

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

Outputs:

foo = "HelloWorld"
Run Code Online (Sandbox Code Playgroud)

使用新值会否定默认设置local

$ terraform apply -auto-approve -var="foo=HelloUniverse"

...

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

Outputs:

foo = "HelloUniverse"
Run Code Online (Sandbox Code Playgroud)