【问题标题】:Is there a way AND/OR conditional operator in terraform?terraform 中是否有 AND/OR 条件运算符?
【发布时间】:2017-01-21 15:13:58
【问题描述】:

有没有办法在 Terraform 中使用类似的东西?

count = "${var.I_am_true}"&&"${var.I_am_false}"

【问题讨论】:

  • 我想不是上次我检查了。但是您可能会从他们的问题跟踪中找到一些东西:github.com/hashicorp/terraform/issues
  • 对于 Terraform 0.11 (2018),请参阅下面的答案

标签: terraform


【解决方案1】:

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

支持的运算符有:

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

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

条件一和条件二:

count = var.condition_one && var.condition_two ? 1 : 0

condition_one 和 NOT condition_two:

count = var.condition_one && !var.condition_two ? 1 : 0

条件一或条件二:

count = var.condition_one || var.condition_two ? 1 : 0

【讨论】:

  • 这应该是当前 tf 版本的公认答案。
【解决方案2】:

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

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

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

在上面的代码中,只有当var.foo AND var.bar 都是true 时,count 才会为 1,因为 1 * 1 是 1。在所有其他情况下 (1 * 0, 0 * 1, 0 * 0),你得到 0。

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

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

在上面的代码中,如果 var.foovar.bartruecount 将为 1,并且仅当两者都是 falsesignum(1 + 1) = 1signum(1 + 0) = 1signum(0 + 1) = 1,@)时为 0 987654348@)。

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

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

不是这个:

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

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

【讨论】:

    【解决方案3】:

    Terraform 0.8 添加了对conditional logic 的一流支持,而不是以前的变通办法。

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

    variable "env" { default = "development" }
    
    resource "aws_instance" "production_server" {
      count = "${var.env == "production" ? 1 : 0}"
      ...
    }
    

    现在这只会在env 设置为"production" 时创建production_server EC2 实例。

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

    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}"
    }
    

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

    这意味着你不能像我最近的例子那样尝试解决aws_route53_zone data source 的问题:

    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_iddata.aws_route53_zone.public_zone.zone_id,具体取决于 public_zone 设置为 true 还是 false。

    【讨论】:

      【解决方案4】:

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

      例如

      或等效

       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,两者都可以工作。

      不过没试过。

      【讨论】:

        【解决方案5】:

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

        例如,您有 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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-02-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-29
          相关资源
          最近更新 更多