Создание ресурсов Terraform из значений JSON - PullRequest
1 голос
/ 10 января 2020

Я ищу способ генерирования кода Terraform на основе значений JSON. Представьте, что у меня есть файл JSON со следующей структурой:

{
  "settings": [
    {
      "conf": [
        {
          "setting": "DeploymentPolicy",
          "namespace": "aws:elasticbeanstalk:command",
          "value": "AllAtOnce"
        },
        {
          "setting": "BatchSize",
          "namespace": "aws:elasticbeanstalk:command",
          "value": "30"
        },
        {
          "setting": "BatchSizeType",
          "namespace": "aws:elasticbeanstalk:command",
          "value": "Percentage"
        }
      ]
    }
  ]
}

Я хочу сделать следующее: Создание рабочего ресурса Terraform на основе значений файла JSON, например, среды beanstalk, такой как this:

resource "aws_elastic_beanstalk_environment" "app_prod" {
  name                   = "${aws_elastic_beanstalk_application_version.app.name}-prod"
  application            = aws_elastic_beanstalk_application.app.name
  solution_stack_name    = data.aws_elastic_beanstalk_solution_stack.latest_linux_java.name
  wait_for_ready_timeout = "10m"
  version_label          = aws_elastic_beanstalk_application_version.app.name

  # Elastic beanstalk configuration
  setting {
    name      = "DeploymentPolicy"
    namespace = "aws:elasticbeanstalk:command"
    value     = "AllAtOnce"
  }
  setting {
    name      = "BatchSize"
    namespace = "aws:elasticbeanstalk:command"
    value     = "30"
  }

  ...

}

Поэтому мне нужно создать блок настроек в HCL (конфигурация Terraform) на основе значений JSON. Это означает, что файл JSON, приведенный выше, должен привести к:

  setting {
    name      = "DeploymentPolicy"
    namespace = "aws:elasticbeanstalk:command"
    value     = "AllAtOnce"
  }
  setting {
    name      = "BatchSize"
    namespace = "aws:elasticbeanstalk:command"
    value     = "30"
  }
  setting {
    name      = "BatchSizeType"
    namespace = "aws:elasticbeanstalk:command"
    value     = "Percentage"
  }

Как видите, структура JSON и HCL очень похожа, но не идентична. Смотрите, например, settings, conf или setting вместо name в JSON.

. Возможный подход - прочитать значения JSON и сохранить их в массиве или на карте. Но я понятия не имею, как я могу сгенерировать действительный HCL и добавить его в нужную часть ресурса. Кроме того, я попытался использовать шаблон, но Terraform не поддерживает циклическую функциональность, которая мне нужна для перебора параметров.

Подводя итог:

  • Входные данные - JSON файл это должно быть прочитано
  • JSON содержит настройки (помимо другой информации)
  • Количество настроек может отличаться
  • Каким-то образом мне нужно сгенерировать блок настроек
  • Каким-то образом мне нужно вставить этот блок настроек в ресурс

У кого-нибудь есть идеи, как это сделать? Любые другие подходы? Большое спасибо!

1 Ответ

2 голосов
/ 11 января 2020

Предполагая, что ваш объект JSON находится в файле с именем settings.json в каталоге вашего модуля, вы можете сделать что-то вроде этого:

locals {
  environment_settings = jsondecode(file("${path.module}/settings.json")).settings[0].conf[0]
}

resource "aws_elastic_beanstalk_environment" "app_prod" {
  name                   = "${aws_elastic_beanstalk_application_version.app.name}-prod"
  application            = aws_elastic_beanstalk_application.app.name
  solution_stack_name    = data.aws_elastic_beanstalk_solution_stack.latest_linux_java.name
  wait_for_ready_timeout = "10m"
  version_label          = aws_elastic_beanstalk_application_version.app.name

  dynamic "setting" {
    for_each = local.environment_settings
    content {
      namespace = setting.value.namespace
      name      = setting.value.setting
      value     = setting.value.value
    }
  }
}

Этот специальный dynamic блок является своего рода макросом для создания повторяющихся setting блоков, каждый из которых коррелирует с одним элементом коллекции, заданным в for_each.

Вы можете делать любые преобразования ввода, которые вам нужны, используя язык выражений Terraform в блок locals, чтобы убедиться, что значение local.environment_settings содержит один элемент для каждого блока setting, который вы сгенерируете, а затем в вложенном блоке content сообщите Terraform, как заполнять аргументы setting на основе значений этих элементов .

...