Я не особенно знаком с этим форматом 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 для этого провайдера, чтобы упростить этот вариант использования.