
Grafana CloudのダッシュボードをJSONでローカル管理・同期してみた
はじめに
Grafanaのダッシュボードを作っているとコードベースで構築できたらいいのにな〜と思うことはありませんか?
私はあります。
最近はClaude Codeなど、CLIベースのAIコーディングエージェントを使うことも多いので、よりコードベースで構築したいと思うことが多くなりました。
そこで、Grafanaダッシュボードのjsonファイルをローカルで管理しながらダッシュボードの構築をやってみたいと思います。
前提として今回はGrafana Cloudを利用しています。
ダッシュボードのjsonファイルって?
Grafanaでダッシュボードを作成すると、その裏ではダッシュボードを定義するjsonファイルが作成されています。
このjsonファイルにはダッシュボード設定、パネル設定、レイアウト、クエリなどが含まれます。
具体的には、作成したダッシュボードの
設定 > JSONモデル
の順に進むとjson形式でダッシュボードの定義が表示されます。
このjsonファイルの中身を変更することでダッシュボードにも変更内容が適用されます。
今回はこのjsonファイルをローカル環境で変更して、Grafana側にアップロードすることで、あたかもローカル環境からコードベースでダッシュボードを管理しているかのようなことを実現してみたいと思います。
事前準備
事前にローカル環境からjsonファイルをダウンロード、アップロードできるように、GrafanaのURLとAPIキーを取得します。
Grafana URL
次のURLにアクセスします。
ログインすると自身のGrafana URLが表示されるのでコピーします。APIキー
左のメニューより、
管理 > ユーザーとアクセス > サービスアカウント
サービスアカウントを追加をクリック
サービスアカウントを作成します。
表示名は適当にDashboard-Syncと入力して、役割はEditorにしておきます。
サービスアカウントが作成されたらサービスアカウントトークンを追加をクリックします。
発行されたトークンをコピーします。
接続確認
取得したURLとAPIキーで接続できることを確認します。
まずは環境変数に取得した値を入力します。
export GRAFANA_URL="ここにURL"
export GRAFANA_API_KEY="ここにAPI KEY"
以下のコマンドでダッシュボードの一覧が取得できればGrafana Cloudへ接続ができています。
$ curl -s \
"${GRAFANA_URL}/api/search?type=dash-db" \
-H "Authorization: Bearer ${GRAFANA_API_KEY}" | \
jq -r '.[] | "- \(.title)"'
- demo-dashboard
- ...
jsonファイルのダウンロード
デモ用のダッシュボード作成
接続の確認までできたので、まずは今回の検証用に空のダッシュボードを作成します。
まだ何もパネルは作成していない状態です。
jsonファイルのダウンロード
次に、作成したダッシュボードのjsonファイルをダウンロードします。
UI上からもダウンロードできますが、今回はCLIでダウンロードします。
まずはダッシュボードのUIDを調べます。
$ curl -s "${GRAFANA_URL}/api/search?query=demo-dashboard" \
-H "Authorization: Bearer ${GRAFANA_API_KEY}" | \
jq -r '.[] | "Title: \(.title), UID: \(.uid)"'
Title: demo-dashboard, UID: yoqmzdw
UIDが分かりました。
次に作成したダッシュボードのjsonファイルをダウンロードします。
$ curl -s "${GRAFANA_URL}/api/dashboards/uid/yoqmzdw" \
-H "Authorization: Bearer ${GRAFANA_API_KEY}" | \
jq '.dashboard' > demo-dashboard.json
ファイルがローカル環境にダウンロードされました。
$ ls
demo-dashboard.json
jsonファイルの更新
ではjsonファイルを更新してパネルを1つ追加してみます。
今回はAWSのコストと使用状況レポート(CUR)をデータソースとしているので、過去7日間のコストレポートのパネルを追加します。
Claude Codeに過去7日間のコストレポートを表すパネルを1つ追加してとお願いしてみます。
- "rawSQL": "",
+ "rawSQL": "SELECT\n DATE(line_item_usage_start_date) as time,\n SUM(line_item_unblended_cost) as
total_cost\nFROM cur_db.cur_table\nWHERE line_item_usage_start_date >= CURRENT_DATE - INTERVAL '7' DAY\n
AND line_item_usage_start_date <= CURRENT_DATE\nGROUP BY DATE(line_item_usage_start_date)\nORDER BY
DATE(line_item_usage_start_date);",
+ total_cost\nFROM cur_db.cur_table\nWHERE line_item_usage_start_date >= CURRENT_DATE - INTERVAL '7'
+ DAY\n AND line_item_usage_start_date <= CURRENT_DATE\nGROUP BY DATE(line_item_usage_start_date)\nORDER BY
+ DATE(line_item_usage_start_date);",
- "title": "新規パネル",
+ "title": "過去7日間のコスト推移",
それっぽいSQLが作成されたのでjsonファイルに適用します。
jsonファイルのアップロード
更新したjsonファイルをダッシュボードに反映させます。
$ jq -n --argjson dashboard "$(cat demo-dashboard.json)" \
'{"dashboard": $dashboard, "overwrite": true}' | \
curl -X POST "${GRAFANA_URL}/api/dashboards/db" \
-H "A juthorization: Bearer ${GRAFANA_API_KEY}" \
-H "Content-Type: application/json" \
-d @-
{"folderUid":"","id":36,"slug":"demo-dashboard","status":"success","uid":"yoqmzdw","url":"/d/yoqmzdw/demo-dashboard","version":5}
ファイルのダウンロード時にjqコマンドを使ってjsonのペイロードを整形しているため、そのままアップロードするとエラーになります。
そのため上記のコマンドでは先にjqコマンドでjson構造を正規化してからアップロードしています。
それではアップロードしたjsonファイルがダッシュボードに適用されているか確認します。
過去7日間のコスト遷移のグラフが作成されていますね。
逆もやってみる
ちょっとしたい修正はダッシュボード上で行うことも多いと思います。
その場合は
- ダッシュボード上から変更
- ロールファイルとの差分を埋めるためにjsonをダウンロード
とすることで常にjsonファイルを同期しておくことができます。
それではやってみましょう。
手順はjsonファイルをダウンロードした時と同じです。
先ほど作成したグラフは折れ線グラフだったので棒グラフに変更して保存します。
ではjsonファイルをダウンロードします。
今回は折れ線グラフ→棒グラフへ変更したことが分かりやすいように別名でダウンロードします。
# demo-dashboard-bar.jsonとして新たにjsonファイルをダウンロード
$ curl -s "${GRAFANA_URL}/api/dashboards/uid/yoqmzdw" \
-H "Authorization: Bearer ${GRAFANA_API_KEY}" | \
jq '.dashboard' > demo-dashboard-bar.json
diffを見ます。
$ diff demo-dashboard.json demo-dashboard-bar.json
40,43c40
< "barAlignment": 0,
< "barWidthFactor": 0.6,
< "drawStyle": "line",
< "fillOpacity": 0,
---
> "fillOpacity": 80,
50,51d46
< "insertNulls": false,
< "lineInterpolation": "linear",
53d47
< "pointSize": 5,
57,62d50
< "showPoints": "auto",
< "spanNulls": false,
< "stacking": {
< "group": "A",
< "mode": "none"
< },
91a80,83
> "barRadius": 0,
> "barWidth": 0.97,
> "fullHighlight": false,
> "groupWidth": 0.7,
97a90,92
> "orientation": "auto",
> "showValue": "auto",
> "stacking": "none",
102c97,99
< }
---
> },
> "xTickLabelRotation": 0,
> "xTickLabelSpacing": 0
124c121
< "type": "timeseries"
---
> "type": "barchart"
141c138
< "version": 1
---
> "version": 6
ダッシュボードから変更したことでいくつかの値が変更されていますね。
このようにダッシュボードから変更した場合も、ローカルで変更した場合もjsonファイルを同期させることができました。
私はこのjsonファイルをGit管理することでいつでも任意のタイミングに戻れるようにしています。
まとめ
Grafana ダッシュボードのjsonファイルをCLIベースで管理してみました。
実際にやってみた所感としては、1人でダッシュボードを構築するならこの方法はありだな〜と思いました。
特にClaude Codeとの相性は非常に良いと感じました。
今までGrafanaのようなUIメインのダッシュボードツールはAIを組み合わせてもあまり構築が加速するという印象はありませんでしたが、今回の方法を試してみて期待するダッシュボードを作成するまでの時間がかなり削減されたように感じました。
今後時間があればもう少し自動化を組み込んだり、複数人での開発にも対応できるよな方法を考えてみたいと思います。