我正在尝试编写一些 terraform 代码,它将采用嵌套对象并创建资源,通常这将通过动态块来完成,但所讨论的资源不支持这一点,并且想知道是否有人对解决这个问题的最佳方法有任何想法。
配置如下:
dashboards = {
"Test Dashboards" = {
folder_name = "Test Folder"
dashboards = [
{
file. = "test.json"
overwrite = true
},
{
file = "test1.json"
overwrite = false
}
]
}
}
然后在资源创建中,通常会是这样的:
resource "grafana_dashboard" "dashboards" {
for_each = var.dashboards
folder = each.value.folder_name
dynamic "dashboard" {
for_each = each.value.dashboards
content {
config_json = file("../../dashboards/${dashboards.value["file"]}")
overwrite = dashboards.value["overwrite"]
}
}
}
但是动态块不支持此资源,唯一的方法是我不想重复配置,因为如果有意义的话,它可能与多个资源共享。
在真正回答这个问题之前,我认为有必要澄清一些术语上的分歧:您将输入变量称为“仪表板”,但根据您赋予它的值,它似乎是文件夹的集合,每个文件夹包含一个或多个仪表板。
因此,我认为您真正
grafana_folder
需要的是的每个元素的一个实例var.dashboards
,然后是grafana_dashboard
所有文件夹中列出的每个不同仪表板的一个实例。那么,您在这里所做的本质上是扁平化嵌套结构
for_each
中描述的问题的 Grafana 版本,因此您可以按照如下方式调整其中描述的方法。首先,让我们声明一个输入变量以确保我们同意它的类型:
由于此变量已经是一个映射,并且对于您想要声明的每个“文件夹”已经有一个元素,因此您可以直接使用此值
for_each
来声明多个实例grafana_folder
:仪表板本身比较棘手,因为您需要首先将此数据结构投影到适合一次描述所有仪表板的形状:它必须是一个集合,每个仪表板一个元素,而不是每个文件夹一个元素。这就是
flatten
:local.dashboards
现在是所有仪表板的平面集合,每个仪表板都知道其所属文件夹的密钥。剩下的唯一要求就是将其投影到一个映射中,其中每个元素都有一个唯一的键,Terraform 可以使用它来跟踪哪个资源实例属于它。如果您能保证每个仪表板都有唯一的
file
参数,那么这可能是合适的,我假设在本例中情况确实如此,但如果情况并非如此,则需要引入另一个值来唯一地跟踪每个文件夹中的每个仪表板。这使用
folder_key
每个对象的属性将每个仪表板与其对应的文件夹对象连接起来,因此这应该描述 Grafana 中的层次结构,该层次结构等同于所描述的层次结构var.dashboard_folders
。这可能无法编译;但是,您可以尝试类似的构造,看看它是否能满足您的需求。其思路是将仪表板扁平化/投影到 dashboard_content 结构中,每个 dashboards [] 项对应一个元素,并设置父键 -> folder_name。folder_name 必须唯一,因为这将决定资源的绑定方式。第二个循环在动态部分将扁平化的子项与父项连接起来。
我从未尝试将动态部分中的项目绑定到外部范围中的项目,因此我不确定内部循环是否会编译,但可能值得一试。