AWS で構築するセルフホスト版 Lightdash
Lightdash は、dbt プロジェクト内で定義した dimension や metrics を用いて可視化を行うことができる BI ツールです。データ層と BI/AI 層の中間に位置する抽象化層、いわゆる「セマンティックレイヤー」の整備がデータ利活用における大きな課題として認識されつつありますが、Lightdash は dbt モデルのスキーマ YAML 定義がそのままセマンティックレイヤーとして機能するという点で、昨今特に注目を集めているツールの一つではないかと思います。
そんな Lightdash ですが、利用形態としてセルフホスト版(以下、OSS 版)と Cloud SaaS 版があります。今回、OSS 版 Lightdash を AWS 上に構築してみたので、本記事ではそのアーキテクチャ概要と構築時のポイントについてご紹介できればと思います。
OSS 版と Cloud 版の違いについて
本題に入る前に、OSS 版と Cloud 版の違いについて少し触れておきたいと思います。
OSS 版
OSS 版は、自前のインフラ環境に Lightdash サーバーを構築することで、ライセンス費用なく利用可能な形態です。dbt とのネイティブ統合や、ダッシュボード・可視化の作成 など、基本的なユースケースに対応できます。
Lightdash 自体の利用に費用は発生しませんが、Lightdash が稼働するインフラの金銭的コストや、その構築・保守のための人的コストはかかってきます。また、AI agents のような AI 系の機能など、高度な機能については利用できないようです。
Cloud 版
Cloud 版は SaaS 製品として、Lightdash 社 (Telescope Technology Limited.) とライセンス契約を結ぶことで利用可能な形態です。インフラの構築・保守なく、簡単に利用を開始できます。
利用プランとしては Cloud Starter / Cloud Pro / Enterprise の 3 つが存在します。プランごとに利用可能な機能に違いがあり、前述の AI 機能については Cloud Pro 以上が必要です。
Lightdash Cloud Plan & Pricing - 公式 Docs
ikki さんの記事 にも言及がある通り、Lightdash Cloud は多くの BI 製品が採用しているような「ユーザーアカウント数課金」ではなく「月額固定料金」であるため、ユーザー数が増えるほどコストメリットが大きくなります。
規模感の小さいスタートアップにとっては、基本的な機能の使用感を掴むためにまずは OSS 版から始めてみて、利用規模が拡大してきたら Cloud 版への移行を検討するというのは、導入の道筋として良いかもしれません。
OSS 版のデプロイ方式
OSS 版の場合、基本的には Kubernetes + Helm によるデプロイ方式が推奨されているようです。
ただし、非 Kubernetes 環境での選択肢として Docker Compose や Restack でのデプロイ方法についても言及されています。
docker-compose.yml
を見てみると、Lightdash サーバー以外は MinIO (S3), PostgreSQL DB, Headless Browser があるだけなので、Lightdash の Docker イメージを使用すれば AWS 上で ECS サービスとしても構築できそうです。
アーキテクチャ
以上を踏まえて、今回以下のようなアーキテクチャで構築してみました。
(想定する URL は https://lightdash.example.com
とします)
概要
Docker Hub 上に Lightdash の Docker イメージ lightdash/lightdash があるので、これを元にプライベートサブネット上の ECS サービスとして稼働させます。Lightdash が使用する DB として PostgreSQL が必要なので、今回は Aurora PostgreSQL 17.4 の DB クラスターを構築します。
ECS サービスコンテナをターゲットグループに登録する Application Load Balancer (ALB) を、パブリックサブネット上に構築します。ユーザーからのリクエストは ALB をオリジンとする CloudFront ディストリビューションを経由させるようにしています。
SSO 認証
ECS サービスコンテナの環境変数を定義しておくことで、SSO 認証を実装できます。[1]
認証プロバイダーとしては ( Okta / Google / OneLogin / Microsoft Entra ID / OpenID Connect ) あたりが利用できそうなので、今回は Google OAuth 2.0 を利用したいと思います。(詳細は後述)
実行結果保存用 S3 バケット
Lightdash では、Slack 投稿のプレビュー画像や実行結果(JSONL 形式など)などのファイルの保存先として、S3 互換のオブジェクトストレージを必要とします。[2] ローカル用に MinIO なども利用可能ですが、本記事ではクラウド上にデプロイするので S3 を利用します。
また、Lightdash が稼働する ECS サービスのタスクロールに対して、S3 バケットへの PutObject 権限を付与する必要があります。
その他
その他、Slack・GitHub との統合や E メール通知用の SMTP 設定なども出来そうですが、本記事では最小構成ということで割愛したいと思います。
- Configure a Slack integration for self-hosted Lightdash
- Configure a Github integration for self-hosted Lightdash
- Configure SMTP for Lightdash email notifications
構築手順
例えば以下のような順序で構築を進めると良さそうです。
(Route 53 ホストゾーンの作成や ACM 証明書の作成・検証などに関しては割愛しています)
- 【手順1】 Application Load Balancer (ALB) を作成する
- 【手順2】 ALB をオリジンとする CloudFront ディストリビューションを作成し、ディストリビューションドメイン名を
lightdash.example.com
のエイリアス A レコードとする - 【手順3】実行結果保存用 S3 バケットを作成する
- 【手順4】Lightdash 用 Aurora PostgreSQL データベースを作成する
- 【手順5】Google OAuth 2.0 クライアントを作成する
- 【手順6】機微情報格納用の Secrets Manager シークレットを作成する
- 【手順7】ALB ターゲットグループに登録されるように設定した ECS サービスを作成する
構築時のポイント
各手順の詳細については割愛しますが、構築時のポイントになりそうな点について、以降でいくつか言及しておきたいと思います。
【手順4】Lightdash 用 DB の作成
拡張機能のインストール
Lightdash では PostgreSQL データベースの拡張機能として、uuid-ossp を必要とします。[3]
これは DB 内で UUID を生成するためのものです。
Aurora PostgreSQL データベース作成後、DB 接続して拡張機能一覧を表示すると初期状態で以下のようになっており、UUID を生成しようとしてもエラーになります。
-- 拡張機能一覧の表示
lightdash=> \dx;
List of installed extensions
Name | Version | Schema | Description
---------+---------+------------+------------------------------
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
(1 row)
-- UUID の生成(失敗)
lightdash=> SELECT uuid_generate_v4();
ERROR: function uuid_generate_v4() does not exist
LINE 1: SELECT uuid_generate_v4();
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
以下のように uuid-ossp をインストールすると、UUID を生成できるようになります。
-- 拡張機能のインストール
lightdash=> CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION
-- 拡張機能一覧の表示
lightdash=> \dx;
List of installed extensions
Name | Version | Schema | Description
-----------+---------+------------+-------------------------------------------------
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
uuid-ossp | 1.1 | public | generate universally unique identifiers (UUIDs)
-- UUID の生成(成功)
lightdash=> SELECT uuid_generate_v4();
uuid_generate_v4
--------------------------------------
6996c424-6bb5-4382-918a-89632cbb5f26
(1 row)
【手順5】Google OAuth クライアントの作成
自社ドメインのメールアドレスを持ち、かつ管理者が招待したメンバーのみが SSO ログイン可能という要件で実装してみたいと思います。
- Google Cloud コンソール にログインし、プロジェクトを選択または新規に作成します。
- 検索から「OAuth 同意画面」を選択し、Google Auth Platform を開きます。
- 左メニューの [ クライアント ] より、「クライアントを作成」を押下します。
- 以下の通り入力し、「作成」を押下します。
設定名 値 アプリケーションの種類 ウェブアプリケーション 名前 Lightdash 承認済みの JavaScript 生成元 https://lightdash.example.com
承認済みのリダイレクト URI https://lightdash.example.com/api/v1/oauth/redirect/
google
- 「OAuth クライアントを作成しました」の画面に表示される "クライアントID" および、"クライアントシークレット" の値を控える、または JSON をダウンロードします。
【手順6】Secrets Manager シークレットの作成
AWS Secrets Manager を使用して、シークレットを作成します。
Aurora PostgreSQL データベース認証情報、Lightdash Secret、控えておいた Google OAuth クライアント ID・シークレットなどを管理します。
-
PGHOST
,PGPORT
,PGUSER
,PGPASSWORD
,PGDATABASE
LIGHTDASH_SECRET
-
AUTH_GOOGLE_OAUTH2_CLIENT_ID
,AUTH_GOOGLE_OAUTH2_CLIENT_SECRET
各環境変数の詳細はこちらで確認できます。
【手順7】ECS サービスの作成
ECS タスク定義の環境変数
Secrets Manager シークレット経由で設定するものに加えて、以下あたりの環境変数もタスク定義内で定義しておきます。
環境変数名 | 値の例 | 説明 |
---|---|---|
LIGHTDASH_LOG_LEVEL |
info |
ログレベルを指定 |
SITE_URL |
https://lightdash.example.com |
|
S3_ENDPOINT |
https://s3.ap-northeast-1. amazonaws.com
|
|
S3_BUCKET |
Lightdash 用 S3 バケット名 | ※東京リージョンの場合 |
S3_REGION |
ap-northeast-1 |
※東京リージョンの場合 |
LD_SETUP_ADMIN_EMAIL |
first.last@example.com |
管理者Eメールアドレス |
LD_SETUP_ORGANIZATION_ EMAIL_DOMAIN
|
example.com |
自社Eメールドメイン |
LD_SETUP_ORGANIZATION_ NAME
|
example-corp |
組織名 |
AUTH_DISABLE_PASSWORD_ AUTHENTICATION
|
true |
パスワード認証を無効化 |
AUTH_GOOGLE_ENABLED |
true |
SSO 認証に Google OAuth を 利用 |
ECS タスク定義・ECS サービス
ECS タスク定義の Terraform 実装は例えば以下のようになります。
Terraform 実装例 - locals ブロック
locals {
domain_name = var.env == "prod" ? "example.com" : "${var.env}.example.com"
# コンテナ定義
container_images = {
lightdash = "lightdash/lightdash:0.1740.2"
}
containers = [
{
name = "server"
image = local.container_images.lightdash
portMappings = [
{ containerPort = 8080, hostPort = 8080, protocol = "tcp" },
]
},
{
name = "headless-browser"
image = "ghcr.io/browserless/chromium:v2.24.3"
portMappings = [
{ containerPort = 3000, hostPort = 3000, protocol = "tcp" },
]
},
]
# 環境変数
envvars = {
LIGHTDASH_LOG_LEVEL = "info"
SITE_URL = "https://lightdash.${local.domain_name}"
# S3 Configuration
S3_ENDPOINT = "https://s3.ap-northeast-1.amazonaws.com"
S3_BUCKET = data.aws_s3_bucket.lightdash.id
S3_REGION = "ap-northeast-1"
# Lighdash Setup
LD_SETUP_ORGANIZATION_EMAIL_DOMAIN = "example.com"
LD_SETUP_ORGANIZATION_NAME = "example-corp"
# Authentication
AUTH_DISABLE_PASSWORD_AUTHENTICATION = "true"
AUTH_GOOGLE_ENABLED = "true"
}
environment_variables = [
for name, value in local.envvars : {
name = name
value = value
}
]
# Secrets Manager から取得するシークレット情報
secret_items = [
"PGHOST",
"PGPORT",
"PGUSER",
"PGPASSWORD",
"PGDATABASE",
"LIGHTDASH_SECRET",
"AUTH_GOOGLE_OAUTH2_CLIENT_ID",
"AUTH_GOOGLE_OAUTH2_CLIENT_SECRET",
]
secrets = [
for secret_item in local.secret_items : {
name = secret_item
valueFrom = "${data.aws_secretsmanager_secret.lightdash.arn}:${secret_item}::"
}
]
}
Terraform 実装例 - ECS タスク定義
resource "aws_ecs_task_definition" "default" {
family = local.service_name
cpu = var.task_definition_config.cpu
memory = var.task_definition_config.memory
task_role_arn = aws_iam_role.task.arn
execution_role_arn = data.aws_iam_role.task_execution.arn
# Infrastructure
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
runtime_platform {
operating_system_family = "LINUX"
}
container_definitions = jsonencode([
for container in local.containers : {
name = container.name
image = container.image
cpu = 0
essential = true
portMappings = try(container.portMappings, [])
command = try(container.command, null)
secrets = local.secrets
environment = concat(
local.environment_variables,
[
for name, value in try(container.custom_envvars, {}) : {
name = name
value = value
}
]
)
logConfiguration = {
logDriver = "awslogs"
options = {
awslogs-group = "${aws_cloudwatch_log_group.default.name}"
awslogs-region = var.region
awslogs-stream-prefix = container.name
}
}
}
])
}
Terraform 実装例 - ECS サービス
resource "aws_ecs_service" "default" {
name = local.service_name
cluster = aws_ecs_cluster.default.arn
desired_count = var.service_config.desired_count
task_definition = aws_ecs_task_definition.default.arn
launch_type = "FARGATE"
platform_version = "1.4.0"
propagate_tags = "SERVICE"
enable_ecs_managed_tags = true
deployment_circuit_breaker {
enable = true
rollback = true
}
load_balancer {
container_name = "server"
container_port = 8080
target_group_arn = var.load_balancer.target_group_arn
}
network_configuration {
security_groups = [aws_security_group.default.id]
subnets = var.network.private_subnets
assign_public_ip = false
}
tags = {
Name = local.service_name
}
}
ECS タスクコンテナが起動すると、初回起動時に DB マイグレーションが実行されます。
(もしかしたら ECS サービスの ALB ターゲットグループ関連付けは、DB マイグレーション実行後に追加する必要があるかもしれません)
初回セットアップ
管理者初回ログイン
ブラウザから https://lightdash.example.com
にアクセスし、"Sign up with Google" を押下して SSO 認証します。
遷移先の初期設定画面にて、組織名とロール、各種オプションを設定します。
組織内ユーザーによるセルフサインアップを許可する場合は Allow users with @example.com to join the organization as a viewer
にチェックを入れますが、ここでは一旦外しておきます。
"Next" を押下するとプロジェクト作成画面に遷移し、Lightdash の利用を開始できます。
(プロジェクト作成の手順については後述します)
ユーザーの招待
セルフサインアップを許可しなかった場合には、自社Eメールドメインユーザーであってもログインはできません。
ログインを許可する場合は、管理者からユーザーを招待します。右上プロフィールアイコンの ① "User settings" から、メニューの ② "User management" に遷移すると、新規ユーザーの招待やロール変更、ユーザー削除などができます。
[ + Add user ] を押下し、招待したいユーザーのメールアドレスとロールを設定して "Generate invite" を押下すると、招待用 URL が生成されます。招待されたユーザーが招待用 URL にアクセスすると、ログインできるようになります。
プロジェクトデプロイ
既にデプロイ可能な dbt プロジェクト (Snowflake) がある前提で、最初のプロジェクトのデプロイ方法について紹介します。
プロジェクト作成画面で、"Snowflake" を選択し、遷移先画面で "Using your CLI" を押下します。
実行すべきコマンドが表示されるので、dbt_project.yml
が存在するディレクトリにて、指示の通り実行してみます。
# Lightdash CLI のインストール
% npm install -g @lightdash/cli@0.1740.2
# Lightdash へのログイン
% lightdash login https://lightdash.example.com --token ldpat_xxxxxxxx
✅️ Login successful
Now you can add your first project to lightdash by doing:
⚡️ lightdash deploy --create
Done 🕶
# プロジェクトのデプロイ
% lightdash deploy --create
- SUCCESS> my_first_model
Compiled 1 explores, SUCCESS=1 ERRORS=0
? Add a project name or press enter to use the default: [MyProjectName] MyProjectName
? Do you confirm Lightdash can store your warehouse credentials so you can run queries in Lightdash? Yes
? Do you want to save this answer for next time? Yes
✔ New project MyProjectName created
Successfully deployed project:
⚡️ https://lightdash.example.com/createProject/cli?projectUuid=393e322a-d631-4315-9fbf-bef0d1c50620
Done 🕶
Lightdash の画面に戻ると、無事分析が始められる状態になっていることを確認できました 🎉
さいごに
OSS 版の Lightdash を AWS 上に構築する方法について書いてみました。
今回は dimension や metrics を定義するところまで紹介できませんでしたが、以下あたりのドキュメントを参考に定義できます。
筆者自身はまだ試せていませんが、他にも dbt Write-Back や Dashboards as code など気になる機能がありそうなので、今回構築した環境を使って色々と試していきたいと思います。
最後まで読んでいただき、ありがとうございました。
-
Configure Lightdash to use passwords or SSO for authentication - Lightdash Documentation ↩︎
-
Configure Lightdash to use external storage - Lightdash Documentation ↩︎
-
Configure Lightdash to use an external database - Lightdash Documentation ↩︎

リアルタイム法人調査システム「SimpleCheck」を開発・運営するシンプルフォーム株式会社の開発チームのメンバーが、日々の開発で得た知見や試してみた技術などについて発信していきます。 Publication 運用への移行前の記事は zenn.dev/simpleform からご覧ください。
Discussion