使用jsonette生成文件时terraform validate失败,求正确方案
Terraform 处理动态生成文件的正确模式
核心原则
Terraform 的配置是声明式的,所有作为配置输入的文件必须在 Terraform 执行初始化/验证阶段就存在。如果文件是后续流程生成的,不能直接用file()这类函数读取,得通过资源属性传递。
具体解决方案
1. 用本地执行资源+本地文件资源联动
如果必须在 Terraform 流程内生成文件,可以用local-exec执行jsonette编译,再通过local_file资源读取生成的文件,后续通过该资源的属性引用内容:
resource "null_resource" "generate_dashboard" { triggers = { # 模板文件变化时触发重新生成 template_hash = filemd5("../grafana/dashboards/gateway-single.template.json") } provisioner "local-exec" { command = "jsonette ../grafana/dashboards/gateway-single.template.json > ../grafana/dashboards/gateway-single.rendered.json" } } resource "local_file" "dashboard_json" { filename = "../grafana/dashboards/gateway-single.rendered.json" # 依赖生成资源,确保文件生成后再读取 depends_on = [null_resource.generate_dashboard] } # 引用local_file的content属性作为Grafana面板配置 resource "grafana_dashboard" "gateway" { config_json = local_file.dashboard_json.content }
2. 用external数据源直接捕获生成内容(推荐)
如果jsonette支持直接输出JSON到标准输出,可以跳过写入磁盘,用external数据源直接捕获生成结果,完全避免磁盘文件依赖:
data "external" "generated_dashboard" { program = ["bash", "-c", "jsonette ../grafana/dashboards/gateway-single.template.json | jq -c '{stdout: .}'"] } resource "grafana_dashboard" "gateway" { config_json = data.external.generated_dashboard.result["stdout"] }
注:这里用jq把jsonette的输出包装成JSON键值对,适配
external数据源的输出要求;如果jsonette本身能直接输出符合要求的JSON结构,可简化命令。
3. 预生成文件并纳入版本控制(稳定场景适用)
如果Dashboard模板不常变动,可在提交代码前预生成gateway-single.rendered.json并加入版本控制。CI流程中也可以在执行terraform validate前先运行jsonette编译命令,确保文件存在。
错误根源
Terraform 的file()函数在配置解析阶段执行,此时还没运行任何资源创建/执行逻辑,生成文件尚未创建,因此报错。所有动态生成的内容必须通过资源属性或数据源输出引用,这些都是在Terraform执行阶段完成的,能保证依赖顺序。
内容的提问来源于stack exchange,提问作者user2886057
相关产品推荐
相关产品推荐

