Есть ли условный оператор AND/OR в terraform?

Есть ли способ использовать что-то подобное в Terraform?

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

Ответы

Ответ 1

Ответ deniszh довольно близок, но я подумал, что немного проясню его и очищу синтаксис.

В Terraform логическое значение true преобразуется в значение 1 а логическое значение false преобразуется в значение 0. Поэтому, если у вас есть две логические переменные, var.foo и var.bar, вы можете представить AND используя простое умножение:

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

В приведенном выше коде count будет равен 1, только если var.foo И var.bar являются true, так как 1 * 1 равно 1. Во всех остальных случаях (1 * 0, 0 * 1, 0 * 0) вы получаете 0,

Чтобы представить OR, вы можете воспользоваться функцией signum (x), которая возвращает 1, если x вы передаете, является положительным числом, 0, если x равно 0, и -1, если x - отрицательное число. Принимая это во внимание, здесь OR:

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

В приведенном выше коде count будет равен 1, если либо var.foo ИЛИ var.bar true и 0, только если оба значения false (signum(1 + 1) = 1, signum(1 + 0) = 1, signum(0 + 1) = 1, signum(0 + 0) = 0).

Обратите внимание, что для использования вышеприведенных методов вы должны позаботиться о том, чтобы установить переменные в логическую и NOT строку. Вы хотите это:

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

Не это:

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

Для получения дополнительной информации о том, как выполнять различные терминологические условия, ознакомьтесь с советами и трюками Terraform: циклы, if-statements и gotchas и Terraform: Up & Running.

Ответ 2

Это более уместно в реальной версии (0.12.X)

Поддерживаемые операторы:

Equality: == и !=
Numerical comparison: >, <, >=, <=
Boolean logic: &&, ||, unary !

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

условие_одно и условие два:

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

Ответ 3

Terraform 0.8 добавила поддержку первого класса для условной логики, а не предыдущие хакерские обходные пути.

Это использует классический тернарный синтаксис, поэтому теперь вы можете сделать что-то вроде этого:

variable "env" { default = "development" }

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

Теперь это создаст экземпляр экземпляра production_server EC2, если env установлен в "production".

Вы также можете использовать его в других местах, например, для установки переменной/параметра следующим образом:

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 данных aws_route53_zone:

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 нет двоичного типа. Но вы можете попытаться использовать простую математику

Например

Или эквивалент

 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.

Не пытались оба.