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 "премиум", то вы получите строку подключения служебной шины премиум-класса или стандартную.

Должно быть намного проще создать только один объект и настроить параметры на основе входной переменной. Иметь карту с параметрами для стандартных и параметров для премиум-класса.

Другие вопросы по тегам