Terraform中的条件属性

Bas*_*usa 5 terraform terraform-provider-aws

Terraform是否支持条件属性?我只想根据变量的值使用属性。

例:

resource "aws_ebs_volume" "my_volume" {
  availability_zone = "xyz"
  size              = 30

  if ${var.staging_mode} == true:
    snapshot_id = "a_specific_snapshot_id"
  endif
}
Run Code Online (Sandbox Code Playgroud)

上面if包含该属性的语句snapshot_id是我要寻找的。Terraform是否基于变量的值支持这种属性包含。

yda*_*coR 6

Terraform 0.12(尚未发布)还将带来对HCL2的支持,支持使您可以将可空参数与以下内容一起使用:

resource "aws_ebs_volume" "my_volume" {
  availability_zone = "xyz"
  size              = 30
  snapshot_id       = "staging_mode ? a_specific_snapshot_id : null"
}
Run Code Online (Sandbox Code Playgroud)

Nullable arguments are covered in this 0.12 preview guide.

For now, pre 0.12, Markus's answer is probably your best bet although I'd be more explicit with the count with something like this:

resource "aws_ebs_volume" "staging_volume" {
   count=${var.staging_mode ? 1 : 0}
   availability_zone = "xyz"
   size = 30

   snapshot_id = "a_specific_snapshot_id"
}

resource "aws_ebs_volume" "non_staging_volume" {
   count=${var.staging_mode ? 0 : 1}
   availability_zone = "xyz"
   size = 30
}
Run Code Online (Sandbox Code Playgroud)

Note that the resource names must be unique or Terraform will complain. This then causes issues if you need to refer to the EBS volume such as with an aws_volume_attachment as in pre 0.12 the ternary expression is not lazy so something like this doesn't work:

resource "aws_volume_attachment" "ebs_att" {
  device_name = "/dev/sdh"
  volume_id   = "${var.staging_mode ? aws_ebs_volume.staging_volume.id : aws_ebs_volume.non_staging_volume.id}"
  instance_id = "${aws_instance.web.id}"
}
Run Code Online (Sandbox Code Playgroud)

Because it will attempt to evaluate both sides of the ternary where only one can be valid at any point. In Terraform 0.12 this will no longer be the case but obviously you could solve it more easily with the nullable arguments.


小智 6

现在 Terraform v0.12 和相应的 HCL2 已发布,您只需将默认变量值设置为“null”即可实现此目的。从 Terraform 网站看这个例子:

variable "override_private_ip" {
  type    = string
  default = null
}

resource "aws_instance" "example" {
  # ... (other aws_instance arguments) ...

  private_ip = var.override_private_ip
}
Run Code Online (Sandbox Code Playgroud)

更多信息在这里:

https://www.hashicorp.com/blog/terraform-0-12-conditional-operator-improvements


Mar*_*kus 5

我不知道这种功能,但是,如果您的案例不太复杂,则可以对此建模。由于布尔值truefalse被认为是10,因此您可以在一个计数内使用它们。所以你可以用

provider "null" {}

resource "null_resource" "test1" {
   count= ${var.condition ? 1 : 0}
}
resource "null_resource" "test2" {
   count = ${var.condition ? 0 : 1}
}

output "out" {
    value = "${var.condition ? join(",",null_resource.test1.*.id) : join(",",null_resource.test2.*.id) }"
}
Run Code Online (Sandbox Code Playgroud)

由于该count属性,仅创建两个资源之一。

您必须使用join这些值,因为这似乎可以很好地处理两个值之一的不存在。

感谢ydaetskcor回答中指出了变量处理方面的改进。