terraform中是否有方法和/或条件运算符?

时间:2016-09-13 22:23:10

标签: terraform

有没有办法在Terraform中使用这样的东西?

  

count =“$ {var.I_am_true}”&&“$ {var.I_am_false}”

5 个答案:

答案 0 :(得分:16)

这在实际版本(0.11.X)中更合适

  

支持的运算符为:

     

平等:==和!=
   数值比较:>,<,> =,<=
   布尔逻辑:&&,||,一元!

https://www.terraform.io/docs/configuration/interpolation.html#conditionals

condition_one和条件2:

count = "${var.condition_one && var.condition_two ? 1 : 0}"

contiion_one和NOT condition_two:

count = "${var.condition_one && !var.condition_two ? 1 : 0}"

condition_one或condition_two:

count = "${var.condition_one || var.condition_two ? 1 : 0}"

答案 1 :(得分:13)

deniszh的答案非常接近,但我想我会澄清它并清理语法。

在Terraform中,布尔值true转换为1,布尔值false转换为0。因此,如果您有两个布尔变量var.foovar.bar,则可以使用简单乘法表示AND

count = "${var.foo * var.bar}"

在上面的代码中,count仅在var.foovar.bar都是true时为1,因为1 * 1为1.在所有其他情况下(1 * 0,0 * 1,0 * 0),得到0。

要表示OR,您可以利用函数signum(x),如果传入的x为正数,则返回1,如果x为0,则返回0,以及 - 如果x是负数,则为1。考虑到这一点,这里是OR:

count = "${signum(var.foo + var.bar)}"

在上面的代码中,如果countvar.foovar.bartrue将为1;如果两者均为false,则{0}将为signum(1 + 1) = 1 }},signum(1 + 0) = 1signum(0 + 1) = 1signum(0 + 0) = 0)。

请注意,要使用上述技术,必须注意将变量设置为布尔值而不是字符串。你想要这个:

variable "foo" {
  # Proper boolean usage
  default = true
}

不是这个:

variable "foo" {
  # THIS WILL NOT WORK!
  default = "true"
}

有关如何执行各种Terraform条件的详细信息,请查看Terraform tips & tricks: loops, if-statements, and gotchas Terraform: Up & Running

答案 2 :(得分:7)

Terraform 0.8conditional logic添加了一流的支持,而不是以前的hacky解决方法。

这使用经典的三元语法,所以你现在可以这样做:

$xml.SelectSingleNode("//*[ns:ONAME='O2']/ns:E1/ns:ANAME[.='A1']", $nameSpace)

现在,这只会在variable "env" { default = "development" } resource "aws_instance" "production_server" { count = "${var.env == "production" ? 1 : 0}" ... } 设置为production_server时创建env EC2实例。

您也可以在其他地方使用它,例如像这样设置变量/参数:

"production"

有一点需要注意的是Terraform在选择三元语句中使用的值之前实际评估双方,而不是懒惰地评估逻辑将触发的三元一侧。

这意味着你不能做这样的事情,就像我最近试图解决aws_route53_zone data source的问题一样:

variable "env" { default = "development" }
variable "production_variable" { default = "foo" }
variable "development_variable" { default = "bar" }

output "example" {
  value = "${var.env == "production" ? var.production_variable : var.development_variable}"
}

在上面的示例中,这将导致计划失败,因为variable "vpc" {} variable "domain" {} variable "private_zone" { default = "true" } data "aws_vpc" "vpc" { filter { name = "tag-key" values = [ "Name" ] } filter { name = "tag-value" values = [ "${var.vpc}" ] } } data "aws_route53_zone" "private_zone" { count = "${var.private_zone == "true" ? 1 : 0}" name = "${var.domain}" vpc_id = "${data.aws_vpc.vpc.id}" private_zone = "true" } data "aws_route53_zone" "public_zone" { count = "${var.private_zone == "true" ? 0 : 1}" name = "${var.domain}" private_zone = "false" } output "zone_id" { value = "${var.private_zone == "true" ? data.aws_route53_zone.private_zone.zone_id : data.aws_route53_zone.public_zone.zone_id}" } data.aws_route53_zone.private_zone.zone_id未定义,具体取决于data.aws_route53_zone.public_zone.zone_id是设置为true还是false。

答案 3 :(得分:1)

Terraform中没有定义二进制类型。但您可以尝试使用simple math

E.g。

OR等效

 count = signum(${var.I_am_true} + ${var.I_am_false})

等效

 count = ${var.I_am_true} * ${var.I_am_false}

如果I_am_true == 1且I_am_false == 0,则两者都有效。

但是,不要试试这两个。

答案 4 :(得分:1)

所有的答案都足够了,但还有另一种情况。

例如,您有 multiple 环境,例如;

  • master
  • dev
  • staging

并且您需要根据这些环境设置 OBJECT_ENABLE 键的值。你可以这样做:

OBJECT_ENABLE = var.app_env == "master" || var.app_env == "dev" ? "true" : "false"

根据上面的条件OBJECT_ENABLE键的值会如下;

对于 masterOBJECT_ENABLEtrue

对于 devOBJECT_ENABLEtrue

对于 stagingOBJECT_ENABLEfalse