Я настраиваю модуль терраформирования для создания кластера полярных сияний.
Мне нужна возможность межрегиональной репликации, поэтому мне нужно выбрать регион реплики по отношению к исходному региону.
Есть ли способ сделать несколько опций условными в terraform?
В Terraform нет такого понятия, как if/elseif/else < 0,12
Однако вы можете использовать классическую логическую логику в Условия Террафом.
Это один из способов использования функции «coalesce()»:
locals{
prod = "${var.environment == "PROD" ? "east" : ""}"
prod2 = "${var.environment == "PROD2" ? "west2" : ""}"
nonprod = "${var.environment != "PROD" && var.environment != "PROD2" ? "west" : ""}"
region = "${coalesce(local.prod,local.prod2, local.nonprod)}"
}
Вы можете попробовать просто использовать map
и lookup
. Пример:
/* In your variables.tf */
variable "region_mapping" {
description = "mapping for cross-region replication"
default = {
"us-east-1" = "us-east-2",
"us-west-1" = "us-west-2"
}
}
/* Then create use lookup to get the replication region from the deployment region */
resource "example" "example" {
region = "${lookup(var.region_mapping, var.region)}"
}
Если var.region
— это место, где у вас развернут ваш текущий кластер, и его значение, например, us-east-1
, то поиск вернет us-east-2
в качестве региона, в котором вы должны развернуть свою реплику.
Отрегулируйте это в соответствии с вашими потребностями.
Начиная с terraform 0.12, вы можете подделать переключатель, используя карты, например.
locals {
environments = {
prod = "east",
prod2 = "west2"
}
region = lookup(environment_region, lower(var.environment), "west")
}
Преимущество этого в том, что если результат более сложный, вы можете вернуть объекты/списки с карты, а не простые строки.
Например, у меня есть централизованный модуль именования, который составляет имя по разным правилам в зависимости от типа ресурса и т. д.
locals {
parts_map = {
# NB Location should always be last to ensure geo-separation of names
prefix = [ local.type.code, var.name, var.role, var.environment, module.location.code ]
suffix = [ var.name, var.role, var.environment, local.type.code, module.location.code ]
mode3 = [ var.name, local.type.code, var.role, var.environment, module.location.code ]
}
parts = compact(local.parts_map[local.type.order])
locals {
test = "${ condition ? value : (elif-condition ? elif-value : else-value)}"
}
Для более буквального подхода «if-elif-else» вы можете вставить короткую руку if с другими, чтобы получить аналогичный эффект. Если ваш вариант использования также находится внутри цикла for, вы также можете сделать это:
locals {
test = {
for i in list :
key => "${ condition ? value : (elif-condition ? elif-value : else-value)}"
}
}
Будет работать в любой ситуации, когда вы будете использовать синтаксис "$ {}"
Я имел дело с этим в течение нескольких часов, пытаясь создать массив для достижения моего требования. Основываясь на ответе @MrJ1m0thy, я создаю эту тройку с несколькими параметрами, которые эмулируют if/elseif/else:
conditioning_a != "condition_a" ? "value1" : (conditioning_b == "condition_b" ? "value_b" : (conditioning_c == "condition_c" ? "value_c" : (conditioning_d == "condition_d" ? "value_d" : "value2")))
Это помогает, в итоге я использую список вместо карты, для которой мне нужен count.index, чтобы найти значение, спасибо @Esteban Garcia