Как использовать массив в качестве входных данных в terrarunt, который принимает только строку в terraform

Опишите ошибку

у нас есть код terraform для хранилища ключей (Azure), в котором идентификатор объекта представляет собой строку для политик доступа. но хотел предоставить в виде массива, т.е. несколько идентификаторов пользователя (идентификатор объекта) в одном идентификаторе объекта.

Действия по воспроизведению проблемы.

main.tf:

resource "azurerm_key_vault" "example" {
  name                        = "examplekeyvault"
  location                    = azurerm_resource_group.example.location
  resource_group_name         = azurerm_resource_group.example.name
  enabled_for_disk_encryption = true
  tenant_id                   = data.azurerm_client_config.current.tenant_id
  soft_delete_retention_days  = 7
  purge_protection_enabled    = false
  sku_name                    = "standard"

  dynamic "access_policy" {
    for_each = var.access_policies
    content {
      tenant_id = data.azurerm_client_config.current.tenant_id
      object_id = access_policy.value["object_id"]
      secret_permissions = access_policy.value["secret_permissions"]
      key_permissions = access_policy.value["key_permissions"]
    }
  }
}

переменные.tf:

variable "access_policies" {
  type = set(
  object({
    object_id = string,
    secret_permissions = set(string),
    key_permissions = set(string)
    })
  )
}

хранилище ключей > terragrunt.hcl:

    input  = {
    access_policies = [

    { object_id = "xyz", secret_permissions = ["Get","Set"], key_permissions = ["Get"] },
    { object_id = "abc", secret_permissions = ["Get"], key_permissions = ["Get"] } ]

приведенный выше код работает нормально

Ожидается поведение, как показано ниже...

я хочу сохранить идентификатор объекта как массив, а также секретное разрешение и разрешение ключа в 1 строке... что-то вроде ниже, которое не работает, даже если сохранить object_id = set(string) в переменных.tf

    { object_id = ["xyz","abc"], secret_permissions = ["Get","Set"], key_permissions = ["Get"] },

на самом деле я хотел сохранить идентификаторы этих объектов как общие в файле global_var.hcl, чтобы вся среда могла использовать один и тот же object_id, а не локальный файл terragrunt.

=============================================== =================

Я попробовал установить (строку) для идентификатора объекта в файле varaibles.tf, как показано ниже, но проблема все еще существует.

ОШИБКА – object_id должен быть строкой

переменные.tf:

variable "access_policies" {
  type = set(
    object({
    object_id = set(string),
    secret_permissions = set(string),
    key_permissions = set(string)
    })
  )
}

Откуда возникает ошибка? Вы используете модули? Если да, то существует ли одна и та же переменная как в корневом, так и в дочернем модулях?

Marko E 21.06.2024 17:11

Ошибка: динамическая «access_policy» > «идентификатор объекта», ожидается только строка...

Ashraf Baig 21.06.2024 17:15

Вы можете попробовать с object_id = ["xyz"]. Но это должно решить только одну часть проблемы.

Marko E 21.06.2024 17:17

Я уже пробовал это, он показывает: «ОШИБКА — object_id должен быть строкой», он не принимается в массиве для object_ID.. я отредактировал это в теле вопроса…

Ashraf Baig 21.06.2024 17:23

Хорошо, это потому, что object_id имеет единственное значение, т. е. это означает, что он может принимать только одно значение.

Marko E 21.06.2024 17:26

да... даже я на той же странице... Но как заставить его принимать массив идентификаторов объектов... может быть, мы можем использовать цикл for дважды... не знаю, как поместить в код

Ashraf Baig 21.06.2024 17:51

@Marko E - Есть идеи по этому поводу?

Ashraf Baig 25.06.2024 10:08
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
105
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я уже пробовал это, он показывает: «ОШИБКА — object_id должен быть строкой», он не принимается в массиве для object_ID. Я отредактировал это в теле вопроса.

Чтобы обрабатывать несколько object_id в рамках ограничений Terraform, вам необходимо использовать подход вложенного цикла.

  • Спасибо @Marko_E, вложенный цикл включает в себя создание динамического блока для каждой политики доступа, а затем еще одного динамического блока для каждого object_id в этой политике.

Конфигурация Терраформа

переменные.tf:

variable "access_policies" {
  type = list(
    object({
      object_ids         = list(string),
      secret_permissions = list(string),
      key_permissions    = list(string)
    })
  )
}

main.tf:

resource "azurerm_key_vault" "example" {
  name                        = "examplekeyvault"
  location                    = azurerm_resource_group.example.location
  resource_group_name         = azurerm_resource_group.example.name
  enabled_for_disk_encryption = true
  tenant_id                   = data.azurerm_client_config.current.tenant_id
  soft_delete_retention_days  = 7
  purge_protection_enabled    = false
  sku_name                    = "standard"

  dynamic "access_policy" {
    for_each = flatten([for policy in var.access_policies : [
      for object_id in policy.object_ids : {
        object_id          = object_id
        secret_permissions = policy.secret_permissions
        key_permissions    = policy.key_permissions
      }
    ]])
    content {
      tenant_id          = data.azurerm_client_config.current.tenant_id
      object_id          = access_policy.value["object_id"]
      secret_permissions = access_policy.value["secret_permissions"]
      key_permissions    = access_policy.value["key_permissions"]
    }
  }
}

глобальный_var.hcl:

access_policies = [
  { object_ids = ["xyz", "abc"], secret_permissions = ["Get", "Set"], key_permissions = ["Get"] }
]
  • Внешний блок dynamic повторяет каждую политику в var.access_policies. Для каждой политики внутренний блок dynamic повторяет каждый object_id в политике object_ids.

  • Эта вложенная структура работает с каждым object_id индивидуально в рамках его политики.

Результат:

приведенный выше код работал, но у меня есть ошибка. Ошибка: неверное значение для входной переменной в строкеvariable.tf, строка 28: 28: переменная "access_policies" {Неподходящее значение для var.access_policies, заданное с использованием переменной среды TF_VAR_access_policies: элемент 0: атрибут "object_id": требуется строка. Я не настроил переменную TF_VAR_access_policies нигде в своем коде terraform или в конвейере CI/CD.

Ashraf Baig 03.07.2024 10:09

Проверьте, как вы передали Object_id в переменных, потому что он отсутствует.

Suresh Chikkam 04.07.2024 08:59

переменные передаются через файл terragrunt.hcl

Ashraf Baig 08.07.2024 17:35

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