Terraform присвоит значение по умолчанию локальной переменной
В моих переменных.tfvars есть следующий код:
variable "is_premium_service_bus_required" {
description = "When set to 1, premium service bus will be created"
type = "string"
default = "0"
}
variable "service_bus_type_cloud" {
description = "Type of service bus to be created, value can only be standard or premium"
type = "string"
}
Следующий код для создания ресурса Azure:
resource "azurerm_servicebus_namespace" "premium-ffdac-cloud-servicebus" {
count = "${var.is_premium_service_bus_required}"
name = "${terraform.workspace}-ffdac-cloud-sbus"
location = "west europe"
resource_group_name = "fusson"
sku = "Premium"
capacity = "1"
}
resource "azurerm_servicebus_namespace" "ffdac-cloud-servicebus" {
name = "${terraform.workspace}-ffdac-cloud-servicebus"
location = "west europe"
resource_group_name = "fusson"
sku = "Standard"
}
Как видно, мы манипулируем созданием ресурса в Azure, устанавливая значение переменной: is_premium_service_bus_required либо равным 0(не создается), либо 1 (создается).
И у меня есть следующие локальные переменные:
locals {
standard_service_bus_cloud_connection_string = "${azurerm_servicebus_namespace.ffdac-cloud-servicebus.default_primary_connection_string};TransportType=Amqp"
}
locals {
premium_service_bus_cloud_connection_string = "${azurerm_servicebus_namespace.premium-ffdac-cloud-servicebus.default_primary_connection_string};TransportType=Amqp"
}
который просто отвечает за управление строкой подключения по умолчанию и добавление протокола в конце.
и у нас есть следующий код, который на основе значения service_bus_type_cloud определяет, какое значение следует присвоить переменной service_bus_cloud_connection_string, которая позже используется в другом файле терраформирования.
locals {
service_bus_type_cloud_names = {
"premium" = "${local.premium_service_bus_cloud_connection_string}"
"standard" = "${local.standard_service_bus_cloud_connection_string}"
}
cloud_connection_string_default = "${local.standard_service_bus_cloud_connection_string}"
service_bus_cloud_connection_string = "${lookup(local.service_bus_type_cloud_names, var.service_bus_type_cloud, local.cloud_connection_string_default)}"
}
Проблема теперь в том, что, когда значение is_premium_service_bus_required установлено в "0", служба лазурной шины премиум-класса не создается, а значение локальной переменной "premium_service_bus_cloud_connection_string" пусто, и мы получаем следующую ошибку:
Error: Error running plan: 1 errors occurred:
* local.premium_service_bus_cloud_connection_string: local.premium_service_bus_cloud_connection_string: Resource 'azurerm_servicebus_namespace.premium-ffdac-cloud-servicebus' not found for variable 'azurerm_servicebus_namespace.premium-ffdac-cloud-servicebus.default_primary_connection_string'
Есть ли способ обойти эту ошибку или лучший способ переписать логику? Мы используем Terraform версии 0.11, поэтому упомянутый здесь условный оператор не может использоваться как следующий код:
locals {
service_bus_cloud_connection_string = "${var.service_bus_type_cloud == "premium" ? "${azurerm_servicebus_namespace.premium-ffdac-cloud-servicebus.default_primary_connection_string};TransportType=Amqp" : "${azurerm_servicebus_namespace.ffdac-cloud-servicebus.default_primary_connection_string};TransportType=Amqp"}"
}
будет оценивать оба выражения значения, даже если когда-либо возвращалось только одно, и, похоже, это ошибка, которая была исправлена в 0.12, как показано здесь
3 ответа
Вы по-прежнему можете использовать условные выражения (Terraform v0.11.14). Вот код.
variable "is_premium_service_bus_required" {
description = "When set to 1, premium service bus will be created"
type = "string"
default = "0"
}
locals {
standard_service_bus_cloud_connection_string = "${var.is_premium_service_bus_required == "0" ? "non_premium_connection_string" : "premium_connection_string"}"
}
output "is_required" {
value = "${local.standard_service_bus_cloud_connection_string}"
}
Вот результат.
[PS][7.0.2] tst > terraform11.exe apply -var "is_premium_service_bus_required=0"
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
is_required = non_premium_connection_string
[PS][7.0.2] tst > terraform11.exe apply -var "is_premium_service_bus_required=1"
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
is_required = premium_connection_string
Как я вижу, вы хотите создать служебную шину с разными типами в соответствии с условием. А затем получите строку подключения служебной шины. Не знаю, нужен ли стандартный тип. Я полагаю, в этом нет необходимости. Затем вы можете изменить это:
variable "is_premium_service_bus_required" {
description = "When set to 1, premium service bus will be created"
type = "bool"
default = true
}
resource "azurerm_servicebus_namespace" "ffdac-cloud-servicebus" {
count = "${var.is_premium_service_bus_required}" ? 1 : 0
name = "${terraform.workspace}-ffdac-cloud-servicebus"
location = "west europe"
resource_group_name = "fusson"
sku = "${var.is_premium_service_bus_required}" ? "Premium" : "Standard"
}
В этой ситуации вы можете получить строку подключения напрямую с помощью "${azurerm_servicebus_namespace.ffdac-cloud-servicebus.default_primary_connection_string};TransportType=Amqp"
как вы отображали в коде.
Но если нужен стандартный тип, было бы немного сложнее:
variable "is_premium_service_bus_required" {
description = "When set to 1, premium service bus will be created"
type = "bool"
default = true
}
variable "service_bus_type_cloud" {
description = "Type of service bus to be created, value can only be standard or premium"
type = "string"
}
resource "azurerm_servicebus_namespace" "premium-ffdac-cloud-servicebus" {
count = "${var.is_premium_service_bus_required}" ? 1 : 0
name = "${terraform.workspace}-ffdac-cloud-sbus"
location = "west europe"
resource_group_name = "fusson"
sku = "Premium"
capacity = "1"
}
resource "azurerm_servicebus_namespace" "ffdac-cloud-servicebus" {
name = "${terraform.workspace}-ffdac-cloud-servicebus"
location = "west europe"
resource_group_name = "fusson"
sku = "Standard"
}
locals {
service_bus_cloud_connection_string = "${var.is_premium_service_bus_required}" && "${var.service_bus_type_cloud}" == "premium" ? "${azurerm_servicebus_namespace.premium-ffdac-cloud-servicebus[0].default_primary_connection_string};TransportType=Amqp" : "${azurerm_servicebus_namespace.ffdac-cloud-servicebus.default_primary_connection_string};TransportType=Amqp"
}
В этой ситуации только тогда, когда переменная is_premium_service_bus_required
верно, а переменная service_bus_type_cloud
"премиум", то вы получите строку подключения служебной шины премиум-класса или стандартную.
Должно быть намного проще создать только один объект и настроить параметры на основе входной переменной. Иметь карту с параметрами для стандартных и параметров для премиум-класса.