Как импортировать шаблон Datadog JSON в terraform DSL? - PullRequest
0 голосов
/ 10 марта 2020
{
   "title":"xxxx",
   "description":"xxx",
   "widgets":[
      {
         "id":0,
         "definition":{
            "type":"timeseries",
            "requests":[
               {
                  "q":"xxxxxx{xxxx:xx}",
                  "display_type":"bars",
                  "style":{
                     "palette":"cool",
                     "line_type":"solid",
                     "line_width":"normal"
                  }
               }
           ]
        }
    ]
}

У меня есть вышеупомянутый шаблон данных json, который я должен импортировать в terraform вместо того, чтобы воссоздать его как terraform dsl.

1 Ответ

1 голос
/ 12 марта 2020

Я не особенно знаком с этим форматом Datadog JSON, но общий шаблон, который я предлагаю здесь, состоит из нескольких шагов:

  • Декодирование сериализованных данных в обычное значение Terraform. В этом случае будет использоваться jsondecode, потому что данные JSON -сериализуются.
  • Преобразуйте и нормализуйте эти необработанные данные в согласованную форму, более удобную для использования в декларативная конфигурация Terraform. Обычно это включает по крайней мере одно именованное локальное значение , содержащее выражение, которое использует for выражения и функцию try вместе с функциями преобразования типов , чтобы попытаться преобразовать необработанные данные в более согласованную форму.
  • Используйте преобразованный / нормализованный результат с конструкциями повторения ресурсов и блоков Terraform (блоки ресурсов for_each и dynamic), чтобы описать, как данные отображаются на физические типы ресурсов.

Вот базовый c пример того, чтобы показать общий принцип. Потребуется больше работы, чтобы собрать все детали, которые вы включили в свой первоначальный пример.

variable "datadog_json" {
  type = string
}

locals {
  raw = jsondecode(var.datadog_json)
  screenboard = {
    title       = local.raw.title
    description = try(local.raw.description, tostring(null))
    widgets = [
      for w in local.raw.widgets : {
        type   = w.definition.type

        title       = w.definition.title
        title_size  = try(w.definition.title_size, 16)
        title_align = try(w.definition.title_align, "center")

        x      = try(w.definition.x, tonumber(null))
        y      = try(w.definition.y, tonumber(null))
        width  = try(w.definition.x, tonumber(null))
        height = try(w.definition.y, tonumber(null))

        requests = [
          for r in w.definition.requests : {
            q            = r.q
            display_type = r.display_type
            style        = tomap(try(r.style, {}))
          }
        ]
      }
    ]
  }
}

resource "datadog_screenboard" "acceptance_test" {
  title       = local.screenboard.title
  description = local.screenboard.description
  read_only   = true

  dynamic "widget" {
    for_each = local.screenboard.widgets
    content {
      type = widget.value.type

      title       = widget.value.title
      title_size  = widget.value.title_size
      title_align = widget.value.title_align

      x      = widget.value.x
      y      = widget.value.y
      width  = widget.value.width
      height = widget.value.height

      tile_def {
        viz = widget.value.type

        dynamic "request" {
          for_each = widget.value.requests
          content {
            q            = request.value.q
            display_type = request.value.display_type
            style        = request.value.style
          }
        }
      }
    }
  }
}

Отдельный шаг нормализации для сборки local.screenboard здесь не является строго необходимым: вместо этого вы можете поставить тот же тип выражений нормализации (используя try для установки значений по умолчанию для неустановленных вещей) непосредственно внутри аргументов блока resource "datadog_screenboard", если хотите. Я предпочитаю рассматривать нормализацию как отдельный шаг, потому что тогда в конфигурации остается четкое определение того, что мы ожидаем найти в JSON и какие значения по умолчанию мы будем использовать для необязательных элементов, отдельно от определения того, как этот результат затем отображается на физический ресурс datadog_screenboard.

Я не смог протестировать приведенный выше пример, потому что у меня нет учетной записи Datadog. Я извиняюсь, если есть небольшие опечатки / ошибки, которые приводят к ошибкам. Я надеялся показать общий принцип сопоставления сериализованного файла данных с ресурсом, а не дать готовое к использованию решение, поэтому я надеюсь, что приведенное выше содержит достаточно примеров различных ситуаций, которые вы можете увидеть, как расширить его для остальные функции Datadog JSON, которые вы хотите поддерживать в этом модуле.


Если этот формат JSON является форматом обмена, официально задокументированным Datadog, для поставщика Datadog Terraform может иметь смысл иметь возможность принимать одну строку JSON в этом формате в качестве конфигурации для упрощения экспорта. Это может потребовать внесения изменений в самого провайдера Datadog, что выходит за рамки того, на что я могу ответить здесь, но, возможно, стоило бы затронуть проблемы GitHub для этого провайдера, чтобы упростить этот вариант использования.

...