如何通过Terraform将Grafana仪表盘导入多实例并解决数据源错误?
如何通过Terraform将仪表盘导入多个Grafana实例?
问题背景
我有多个Grafana实例,需要让所有实例使用相同的仪表盘。已在一个实例上创建并导出仪表盘,现在希望通过Grafana Provider将该仪表盘导入其他Grafana实例,但创建仪表盘后无法打开,报错:
Templating
Failed to upgrade legacy queries Datasource ${DS_MYSQL} was not found
Terraform配置
resource "grafana_data_source" "mysql" { type = "mysql" name = "MySQL" url = "localhost:3306" database_name = "test" username = "dbuser" secure_json_data_encoded = jsonencode({ password = "dbpassword" }) } resource "grafana_dashboard" "metrics" { config_json = file("test.json") }
仪表盘JSON配置
{ "__inputs": [ { "name": "DS_MYSQL", "label": "MySQL", "description": "", "type": "datasource", "pluginId": "mysql", "pluginName": "MySQL" } ], "__elements": {}, "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "10.0.3" }, { "type": "datasource", "id": "mysql", "name": "MySQL", "version": "1.0.0" }, { "type": "panel", "id": "table", "name": "Table", "version": "" } ], "annotations": { "list": [ { "builtIn": 1, "datasource": { "type": "grafana", "uid": "-- Grafana --" }, "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "target": { "limit": 100, "matchAny": false, "tags": [], "type": "dashboard" }, "type": "dashboard" } ] }, "editable": true, "fiscalYearStartMonth": 0, "graphTooltip": 0, "id": null, "links": [], "liveNow": false, "panels": [ { "datasource": { "type": "mysql", "uid": "${DS_MYSQL}" }, "fieldConfig": { "defaults": { "color": { "mode": "thresholds" }, "custom": { "align": "auto", "cellOptions": { "type": "auto" }, "inspect": false }, "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { "color": "green", "value": null }, { "color": "red", "value": 80 } ] } }, "overrides": [] }, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 }, "id": 1, "options": { "cellHeight": "sm", "footer": { "countRows": false, "fields": "", "reducer": [ "sum" ], "show": false }, "showHeader": true }, "pluginVersion": "10.0.3", "targets": [ { "dataset": "test", "datasource": { "type": "mysql", "uid": "${DS_MYSQL}" }, "editorMode": "builder", "format": "table", "rawSql": "SELECT id FROM test.issue LIMIT 50 ", "refId": "A", "sql": { "columns": [ { "parameters": [ { "name": "id", "type": "functionParameter" } ], "type": "function" } ], "groupBy": [], "limit": 50 }, "table": "issue" } ], "title": "Panel Title", "type": "table" } ], "refresh": "", "schemaVersion": 38, "style": "dark", "tags": [], "templating": { "list": [] }, "time": { "from": "now-6h", "to": "now" }, "timepicker": {}, "timezone": "", "title": "DUR Test", "uid": "ff8f4277-eb0b-46ee-abbf-3b668e9bd3a5", "version": 2, "weekStart": "" }
调研情况
- 查阅了Terraform管理Grafana仪表盘的相关内容,未找到数据源关联的解决方法
- 查阅了Grafana Cloud栈的Terraform管理文档,未找到适配的仪表盘JSON示例
- 查阅了Grafana相关Issue,未找到自动化解决方案,不想手动修改所有实例的仪表盘
解决方案
报错核心原因是仪表盘JSON中的${DS_MYSQL}占位符未被替换为目标实例中MySQL数据源的真实UID,以下是两种可行的解决方式:
方法1:Terraform字符串替换(推荐)
修改grafana_dashboard资源配置,用Terraform的replace函数将JSON中的占位符替换为已创建数据源的UID:
resource "grafana_dashboard" "metrics" { config_json = replace(file("test.json"), "${DS_MYSQL}", grafana_data_source.mysql.uid) # 显式声明依赖,确保数据源创建完成后再导入仪表盘 depends_on = [grafana_data_source.mysql] }
方法2:调整导出仪表盘的设置
在导出仪表盘时,勾选「Export for sharing externally」选项,此时导出的JSON会直接使用数据源名称而非UID占位符。但这种方式依赖数据源名称完全一致,灵活性较差,仅适用于所有实例数据源名称统一的场景。
内容的提问来源于stack exchange,提问作者dur
相关产品推荐
相关产品推荐

