Использование карты наборов при создании ресурса

#amazon-web-services #azure #terraform

#amazon-веб-сервисы #azure #терраформирование

Вопрос:

У меня есть карта терраформирования объектов набора, как указано ниже

 variable "BName" {
 type = string
 }
variable "type_names" {
 type = map(object({
 name   = string
 type   = string
 stream = string
 grp    = optional(string)
 }))
}
 

Я также пытаюсь использовать имя_типа в следующем ресурсе. Как мы можем ссылаться на значение из карты наборов при создании ресурса

 resource "azure_resource" "reso" {
  id = az_resource.B_Name.id
  name       = var.type_names.name

 }
resource "az_resource" "B_Name" {
  name        = var.BName
 

}

Как я могу передать это значение в файле terraform.tfvars для создания следующего ресурса. Теперь я пытаюсь пройти следующим образом

  BName  = "Test"
 type_names =   {
   name = "cooper"
   type = "senior"
   stream=  "developer"
   grp   =  "Mid"
}
{
   name = "Mike"
   type = "Junior"
   stream=  "tester"
   grp   =  "entry"
}
 

Комментарии:

1. Не могли бы вы обновить значения переменных в вашем примере? Они имеют тип object , а не map(set(object)) . Кроме того, если вы можете использовать set(object) или map(object) вместо этого, это было бы проще.

2. @MattSchuchard я обновил переменные. Не могли бы вы помочь

3. Если у вас есть map(object) , то вы можете просто использовать for_each мета-аргумент в обычном режиме: terraform.io/docs/language/meta-arguments/for_each.html . Это не работает для вас?

4. но как я мог бы указать значения в terraform.tfvars. Интересно, является ли тот, который я привел, правильным форматом

5. Хорошо, теперь я вижу, что пример документации для map неверен. Я думаю, что на данный момент я могу просто написать ответ.

Ответ №1:

Для создания нескольких ресурсов с одним определением с map(object) переменным вводом существует общий алгоритм и шаблон. Во-первых, нам нужно определение структуры переменной из объявления. Для вашего примера мы имеем:

 variable "type_names" {
  type = map(object({
    name   = string
    type   = string
    stream = string
    grp    = optional(string)
  }))
}
 

где я предполагаю использование экспериментальной функции для необязательных ключей объектов с учетом внешнего вида ключевого optional слова . В этой ситуации полезно, чтобы у ресурса был описательный идентификатор. Это, скорее всего, будет name , поэтому мы можем удалить его из object значения и преобразовать его в map ключ. Обновленное определение с примером default , который соответствует определению типа, будет:

 variable "type_names" {
  type = map(object({
    type   = string
    stream = string
    grp    = optional(string)
  }))
  default = {
    "cooper" = {
      type   = "senior"
      stream = "developer"
      grp    = "Mid"
    },
    "Mike" = {
      type   = "Junior"
      stream = "tester"
      grp    = "entry"
    }
  }
}
 

Затем мы можем легко использовать это для управления несколькими ресурсами с помощью одного определения и входной переменной. Поскольку в примере ресурса в вопросе используются ключи, отличные от предоставленных переменной, мы немного изменим пример ресурса:

 resource "azure_resource" "this" {
  for_each = var.type_names

  # value is the object, so we access object values with standard `.key` syntax
  name   = each.key
  type   = each.value.type
  stream = each.value.stream
  grp    = each.value.grp
}
 

и пространство имен каждого ресурса будет azure_resource.this["<key>"] , например azure_resource.this["Mike"] , , и вы можете получить доступ к его атрибутам в обычном режиме.

Комментарии:

1. Спасибо @MattSchuchard, но я получаю сообщение об ошибке. Это значение по умолчанию несовместимо с ограничением типа переменной: элемент «cooper»: требуется атрибут «name». Должен ли я добавить имя также к карте по умолчанию

2. @tjdoubts Пожалуйста, используйте конфигурацию, которую я предоставил в ответе, и прочитайте объяснение конфигурации. Мой ответ не выдает эту ошибку.