terraform 中有 AND/OR 条件运算符吗?
Is there a way AND/OR conditional operator in terraform?
有没有办法在 Terraform 中使用类似的东西?
count = "${var.I_am_true}"&&"${var.I_am_false}"
Terraform 中没有定义二进制类型。但是你可以尝试使用 simple math
例如
或同等学历
count = signum(${var.I_am_true} + ${var.I_am_false})
AND 等效项
count = ${var.I_am_true} * ${var.I_am_false}
如果 I_am_true == 1 和 I_am_false == 0,两者都有效。
虽然两者都没有尝试。
deniszh 的回答非常接近,但我想我应该澄清一下并清理语法。
在 Terraform 中,布尔值 true
被转换为 1
,布尔值 false
被转换为 0
。因此,如果您有两个布尔变量 var.foo
和 var.bar
,您可以使用简单的乘法表示 AND
:
count = "${var.foo * var.bar}"
在上面的代码中,只有当 var.foo
和 var.bar
都为 true
时,count
才会为 1,因为 1 * 1 为 1。在所有其他情况下(1 * 0, 0 * 1, 0 * 0),你得到 0。
表示OR,可以利用函数signum(x),其中returns如果你传入的x
是正数则为1,如果[=25=则为0 ] 为 0,如果 x
为负数,则为 -1。考虑到这一点,这里是 OR:
count = "${signum(var.foo + var.bar)}"
在上面的代码中,如果 var.foo
或 var.bar
是 true
,count
将为 1,只有当两者都是 false
时,count
才为 0(signum(1 + 1) = 1
、signum(1 + 0) = 1
、signum(0 + 1) = 1
、signum(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 and Terraform: Up & Running。
Terraform 0.8 added first class support for conditional logic 而不是以前的 hacky 解决方法。
这使用了经典的三元语法,所以现在您可以这样做:
variable "env" { default = "development" }
resource "aws_instance" "production_server" {
count = "${var.env == "production" ? 1 : 0}"
...
}
现在这只会在 env
设置为 "production"
时创建 production_server
EC2 实例。
您也可以在其他地方使用它,例如像这样设置 variable/parameter:
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
设置为真还是假。
这个在实际版本中比较合适(0.12.X)
The supported operators are:
Equality: == and !=
Numerical comparison: >, <, >=, <=
Boolean logic: &&, ||, unary !
https://www.terraform.io/docs/configuration/interpolation.html#conditionals
condition_one 条件二:
count = var.condition_one && var.condition_two ? 1 : 0
condition_one 而不是 condition_two:
count = var.condition_one && !var.condition_two ? 1 : 0
condition_one 或 condition_two:
count = var.condition_one || var.condition_two ? 1 : 0
所有的答案都足够了,但还有另一种情况。
例如,您有 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 中使用类似的东西?
count = "${var.I_am_true}"&&"${var.I_am_false}"
Terraform 中没有定义二进制类型。但是你可以尝试使用 simple math
例如
或同等学历
count = signum(${var.I_am_true} + ${var.I_am_false})
AND 等效项
count = ${var.I_am_true} * ${var.I_am_false}
如果 I_am_true == 1 和 I_am_false == 0,两者都有效。
虽然两者都没有尝试。
deniszh 的回答非常接近,但我想我应该澄清一下并清理语法。
在 Terraform 中,布尔值 true
被转换为 1
,布尔值 false
被转换为 0
。因此,如果您有两个布尔变量 var.foo
和 var.bar
,您可以使用简单的乘法表示 AND
:
count = "${var.foo * var.bar}"
在上面的代码中,只有当 var.foo
和 var.bar
都为 true
时,count
才会为 1,因为 1 * 1 为 1。在所有其他情况下(1 * 0, 0 * 1, 0 * 0),你得到 0。
表示OR,可以利用函数signum(x),其中returns如果你传入的x
是正数则为1,如果[=25=则为0 ] 为 0,如果 x
为负数,则为 -1。考虑到这一点,这里是 OR:
count = "${signum(var.foo + var.bar)}"
在上面的代码中,如果 var.foo
或 var.bar
是 true
,count
将为 1,只有当两者都是 false
时,count
才为 0(signum(1 + 1) = 1
、signum(1 + 0) = 1
、signum(0 + 1) = 1
、signum(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 and Terraform: Up & Running。
Terraform 0.8 added first class support for conditional logic 而不是以前的 hacky 解决方法。
这使用了经典的三元语法,所以现在您可以这样做:
variable "env" { default = "development" }
resource "aws_instance" "production_server" {
count = "${var.env == "production" ? 1 : 0}"
...
}
现在这只会在 env
设置为 "production"
时创建 production_server
EC2 实例。
您也可以在其他地方使用它,例如像这样设置 variable/parameter:
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
设置为真还是假。
这个在实际版本中比较合适(0.12.X)
The supported operators are:
Equality: == and !=
Numerical comparison: >, <, >=, <=
Boolean logic: &&, ||, unary !
https://www.terraform.io/docs/configuration/interpolation.html#conditionals
condition_one 条件二:
count = var.condition_one && var.condition_two ? 1 : 0
condition_one 而不是 condition_two:
count = var.condition_one && !var.condition_two ? 1 : 0
condition_one 或 condition_two:
count = var.condition_one || var.condition_two ? 1 : 0
所有的答案都足够了,但还有另一种情况。
例如,您有 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