LightdashのCI/CDをGitHub Actions+AWS CodeBuildで構築した話
はじめに
こんにちは、ナウキャストでデータエンジニアをしているh-miyazawaです。
主に金融機関向けに、Snowflakeを活用したデータ基盤構築やデータの可視化を支援しており、とあるプロジェクトでBIツールとしてLightdashを利用しています。
前回はLightdashのテーブルチャートのTipsを紹介しました。
その際、Lightdashの導入に合わせてCI/CDパイプラインも構築したのですが、後述の問題がありいくつか工夫が必要だったので、今回はその構成を紹介します。
前提条件
本記事の内容はOSS版 Lightdash(バージョン 0.2330.0)に基づいています。
Lightdash CLIを利用したデプロイの流れ
Lightdashのリソースをデプロイするには、Deploy changes to productionに記載のあるようにLightdash CLIを使います。流れは以下の通りです。
# 1. 認証
lightdash login "$LIGHTDASH_URL" --token "$LIGHTDASH_API_KEY"
# 2. Lightdashプロジェクトのデプロイ
lightdash deploy --project-dir <dbtのディレクトリパス> --profiles-dir <profiles.ymlのディレクトリパス> --target <profiles.ymlのターゲット名>
# 3. チャート/ダッシュボードのアップロード
lightdash upload --path <チャート/ダッシュボードYAMLのディレクトリパス> --force
CI/CDでは--tokenオプションでPAT(Personal Access Token)を渡して認証しています。
クラウド版ではサービスアカウントを用いた認証も利用できますが、OSS版では環境変数SERVICE_ACCOUNT_ENABLEDがデフォルトfalseであり、trueに設定したとしてもライセンスキーがなければサービスアカウントは使えません。
認証、デプロイ、アップロードのCLIコマンドはいずれもLightdashのHTTP APIを呼ぶため、CLIの実行元からホスティングしたLightdashへのネットワーク到達が必要です。
Automate with CI/CDでもGitHub ActionsでCLIコマンドを実行する手法が紹介されています。
GitHub Actionsから直接実行できない問題
ナウキャストでは金融機関向けのプロジェクトを手がけており、セキュリティ要件でアプリケーションへの接続元IPを制限しているケースがあります。
今回のプロジェクトでもお客様要件で、Lightdashへの接続元IPを制限しているため、IPが不定なGitHub Actionsランナーから直接Lightdash CLIを実行できないという問題がありました。
GitHub Actions + CodeBuildによる構成
GitHub Actionsランナーの送信元IPはGitHub meta APIで公開されていますが、数千のCIDRブロックが含まれており"We make changes to our IP addresses from time to time."とあるように変更もあるうえ、許可リストに追加することは現実的ではありません。
そこで、GitHub ActionsからVPC内のAWS CodeBuildを起動し、CodeBuildからLightdash CLIを実行する構成にしました。

GitHub ActionsからのCodeBuild実行の流れ
GitHub ActionsからAWS CodeBuildを経由してLightdash CLIを実行する流れです。
CI/CDパイプラインの処理ステップ
今回構築したCI/CDパイプラインではAWS CodeBuildの buildspec.yml で以下の4ステップを実行します。
- Lightdashプロジェクトのデプロイ
- チャート/ダッシュボードのアップロード
- 不要なチャート/ダッシュボードの削除
- ダッシュボードのピン留め
Lightdashプロジェクトのデプロイ
dbt parse はSnowflakeに接続せずに manifest.json を生成できます。
lightdash deploy が必要とするのもこの manifest.json だけなので、dbt parse + --skip-dbt-compile の組み合わせにより、Snowflakeへの接続は行わずにLightdashデプロイを行っています。
dbt clean # キャッシュクリア
dbt deps # 依存パッケージインストール
dbt parse --target <profiles.ymlのターゲット名> # manifest.jsonの生成
lightdash deploy \
--project-dir <dbtのディレクトリパス> \
--profiles-dir <profiles.ymlのディレクトリパス> \
--target <profiles.ymlのターゲット名> \
--skip-dbt-compile # parse済みなのでコンパイルをスキップ
チャート/ダッシュボードのアップロード
lightdash upload はYAMLファイルで定義したチャートとダッシュボードをLightdashに反映します。
今回のCI/CDパイプラインでは、Gitリポジトリの定義を正として常に同期させたいため、--force で変更検知をスキップし全量アップロードしています。
lightdash config set-project \
--name <Lightdashのプロジェクト名> # 対象プロジェクトに切り替え
lightdash upload \
--path <チャート/ダッシュボードYAMLのディレクトリパス> \
--force # 変更検知をスキップして全リソースをアップロード
ちなみに、--force を指定しない場合、CLIはローカルファイルの変更有無をチェックし、変更がなければスキップします。
不要なチャート/ダッシュボードの削除
lightdash upload はリソースの削除を行いません。
ダッシュボード名を変更するなどで、YAMLから削除したリソースがLightdash上に残り続けるため、Lightdash APIを使った独自のスクリプトでクリーンアップしています。
# 1. GitリポジトリのYAMLファイルからslug一覧を取得
local_slugs=$(find <YAMLディレクトリパス> -name "*.yml" -exec yq '.slug' {} \;)
# 2. Lightdash APIでプロジェクト内の全リソースを取得
remote_charts=$(curl -s -H "Authorization: ApiKey $LIGHTDASH_API_KEY" \
"$LIGHTDASH_URL/api/v1/projects/$PROJECT_UUID/charts" | jq -r '.results[]')
remote_dashboards=$(curl -s -H "Authorization: ApiKey $LIGHTDASH_API_KEY" \
"$LIGHTDASH_URL/api/v1/projects/$PROJECT_UUID/dashboards" | jq -r '.results[]')
# 3. Gitリポジトリに存在しないリソースをAPI経由で削除
for uuid in $orphan_dashboard_uuids; do
curl -s -X DELETE -H "Authorization: ApiKey $LIGHTDASH_API_KEY" \
"$LIGHTDASH_URL/api/v1/dashboards/$uuid"
done
for uuid in $orphan_chart_uuids; do
curl -s -X DELETE -H "Authorization: ApiKey $LIGHTDASH_API_KEY" \
"$LIGHTDASH_URL/api/v1/saved/$uuid"
done
ダッシュボードのピン留め
lightdash upload ではピン留め状態は制御できません。
ピン留めしないとチャートやダッシュボードが混在して埋もれてしまうため、デプロイのたびにAPIで自動的にピン留めしています。

※ 上記の画面イメージはデモサイトから取得しました。
ピン留めAPIはトグル動作のため、ピン留め済みに実行すると解除されてしまいます。ダッシュボード一覧の pinnedListUuid が null(未ピン留め)のものだけを対象にしています。
# 1. プロジェクト内の全ダッシュボードを取得
dashboards=$(curl -s -H "Authorization: ApiKey $LIGHTDASH_API_KEY" \
"$LIGHTDASH_URL/api/v1/projects/$PROJECT_UUID/dashboards" | jq -r '.results[]')
# 2. 未ピン留めのダッシュボードのみピン留め
for uuid in $unpinned_dashboard_uuids; do
curl -s -X PATCH -H "Authorization: ApiKey $LIGHTDASH_API_KEY" \
"$LIGHTDASH_URL/api/v1/dashboards/$uuid/pinning"
done
おわりに
Automate with CI/CDで紹介されているGitHub ActionsからLightdash CLIを直接実行する手法では、IP制限の制約をクリアできなかったため、今回はAWS CodeBuildを中継する構成にしました。
本記事の内容が同じようにLightdashを使っている方の参考になれば幸いです。
Discussion