terraform 中是不是有 AND/OR 条件运算符?
Posted
技术标签:
【中文标题】terraform 中是不是有 AND/OR 条件运算符?【英文标题】: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),请参阅下面的答案 【参考方案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.foo
和var.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.foo
或 var.bar
是 true
,count
将为 1,并且仅当两者都是 false
(signum(1 + 1) = 1
,signum(1 + 0) = 1
,signum(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 gotchas 和 Terraform: 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_id
或 data.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
键的值会如下;
对于master
:OBJECT_ENABLE 是true
对于dev
:OBJECT_ENABLE 是true
对于staging
:OBJECT_ENABLE 是false
【讨论】:
以上是关于terraform 中是不是有 AND/OR 条件运算符?的主要内容,如果未能解决你的问题,请参考以下文章