これは エムスリー Advent Calendar 2021 の9日目の記事です。 前日は id:kitagry による、k8sのカスタムリソースで、CronJobの終了を検知してJobを実行する でした。
エムスリーエンジニアリンググループ AI・機械学習チームの笹川です。 趣味はバスケと筋トレで、このところはNBAの2021-2022シーズンが昨シーズンからガラッと様相が変わってめちゃくちゃ面白くなっているのをニヤニヤしながら見ています。
今回は、弊社がクライアント企業様向けに提供しているLookerを用いたダッシュボードのためのアーキテクチャの紹介と、その構成管理のために実装したTerraform providerの実装について紹介します。
クライアント企業様へのダッシュボードの提供
今回提供するダッシュボードは、弊社が運営するプラットフォームであるm3.com上でのマーケティング活動をモニタリングするためのものです。 企業向け管理画面からクライアント企業の担当者様が閲覧することを前提にしており、さまざまなKPIの閲覧や、詳細をドリルダウンして改善アクションに繋げられるものを目指し、 顧客の声を聞きながら現在も機能を磨き込んでいます。
ダッシュボードのアーキテクチャ
今回提供するダッシュボードのためバックエンドのアーキテクチャは以下のようになっています。
まず、今回提供するダッシュボードの画面部分には Looker の embeded dashboard という機能を用いています。 Lookerの特徴として、LookMLと呼ばれるYamlベースのDSLを用いて、データモデルや、ダッシュボードの定義をコードで管理できることがあります。 今回提供するダッシュボードは複数社のクライアント企業様に提供することを前提としているので、定義がコード管理され、似たダッシュボードを高速に量産できることは非常に重要です。
Lookerのダッシュボードから参照するデータは、弊社内で以前から広く使われているBigQueryから引いてきます。 今回は社内向けとは別にダッシュボード専用のGCP projectを切り出し (上図の真ん中のBigQuery project) 、そちらのデータを参照する形とし、後述する厳密な権限管理を実施しています。
アーキテクチャの狙い
このアーキテクチャの狙いは大きく以下の2点です。
- データの可視範囲の厳密な管理
- 横展開の容易さ
まず、1つ目のデータ可視範囲の厳密な管理についてですが、今回はクライアント企業様へのデータ提供となるので、A社向けのダッシュボードにB社のデータが入り込んでしまうことは、絶対に避けねばなりません。 ですので、この点については複数の方法で対策しています。
まず、大元のBigQueryのdatasetを企業ごとに分け当該企業のデータのみに絞り込んでデータ連携をしています。
次に、Looker側で用いるBigQueryのconnectionについてです。connectionで利用するGCPのサービスアカウントは企業ごとに分けて作成し、サービスアカウントに付与する権限を当該企業のdatasetの閲覧のみに限定して付与することで、 別のdatasetを参照しようとしても、connectionがもつ権限でそれを防ぐことができます。
2つ目の横展開の容易さについては、CIによるLookMLの書き換えによって実現しています。
今回提供するダッシュボードは、企業ごとのカスタマイズをほぼ持たず、見えるデータのみを差し替えたような構成になっています。 そのため、ベースとなる1つのダッシュボードに相当するLookMLを開発し、特定ブランチにマージされると、CIによって各企業ごとのコピー作成と、connectionの書き換えなどを行うことで、 新規の企業追加などの際にも、CIの設定を1行追加するのみで実現できるようにしています。 具体的には以下のフローで開発しています。
- 事前にLookerの本番環境はLookMLのrepositoryのrelease branchの変更を検知して本番反映される設定を入れておく
- Looker開発環境にて、ベースのモデルやダッシュボードのLookMLを改修する
- master branchにPRを出しreviewの上mergeする
- master branchへのマージを検知してCIでconnectionなど企業ごとの書き換えを実施して複数社分のダッシュボードの実装を作成しstaging branchにcommitする
- staging branchからrelease branchへのPRを作成しreviewの上mergeしLooker本番環境に反映する
これにより、実際にエンジニアが開発するのは1のステップのみで、後続はreviewが通り次第本番環境の各企業のダッシュボードに変更が反映されるというDXの高い開発環境が構築できています。
このフローの構築には以下の記事が大変参考になりました。
細かな工夫
企業ごとのdatasetへのデータ連携は、ダッシュボード表出用の集計済みのデータマートから、企業ごとに where句
で絞り込んで連携することで実現しています。
弊社ではデータ連携のためのworkflow engineとしてdigdagを使っているのですが、この企業ごとのデータ連携部分でdigdagの for_each
の機能がとても便利でした。
以下のように、連携先としてC社を追加する際には、C社のidをループ範囲に追加することで対応が完了します。
# client関連の連携 _export: values: &COMPANIES - {"id": 1, "name": "company A"} - {"id": 2, "name": "company B"} +load_client_bi_tables: for_each>: company: *COMPANIES _do: +build_table1: sh>: bash tasks/build_datamart.sh ${company.id} ${company.name} sql/table1.sql +build_table2: sh>: bash tasks/build_datamart.sh ${company.id} ${company.name} sql/table2.sql
Terraform providerの実装
バックエンドとなるGCPのインフラはもちろん、Looker自体の構成もコード管理したかったのですが、Lookerには公式のTerraform providerがないので、自前で実装し運用することにしました。 Looker自体もTerraform管理にしたことで、特に重視しているユーザ権限の管理や、その変更経緯が追跡できるようになったことはもちろん、 横展開時に新しいconnectionの作成などが簡単なコピペでできるようになったことがとてもよかったポイントです。
今回実装したproviderは以下です。
https://registry.terraform.io/providers/hirosassa/looker/latest
ベースとした 既存のレポジトリ に対して、contributeする形も考えたのですが、 我々が欲しい機能を削ぎ落とす改修が入っていた点 (おそらくシンプルにして管理を容易にしたかったのだと思われる) と、開発のスピード感を重視して今回は独自にforkして開発を進めることにしました。
providerの開発の詳細については特に述べませんが、以下の公式ドキュメントがとても充実しているので、是非ご覧ください。
既存のproviderと異なる便利ポイントは以下の点です。
- Lookerのグループ管理を直感的なインターフェースで書くことができる
- なぜか既存のproviderにグループに対してユーザや、グループを所属させる機能が実装されているものがなかったので実装しました。とても便利です。
- connectionの管理をLookerのAPIに準拠した形で管理できる
- いくつかの既存実装には機能としてありましたが、BigQueryや、Snowflakeのみの対応となっているものなど、汎用的な実装がありませんでした。
- 実装したもののBigQuery以外のバックエンドに対してテストできていないので、是非contributeお待ちしています。
まとめ
Lookerを用いた埋め込みダッシュボードのバックエンドのアーキテクチャと、構成管理のためのLooker providerについて紹介しました。 開発環境の整備については今後は開発者の増員も見据えて
- LookMLのlinter
- LookMLのtest
などの追加に取り組んでいけたらと思っています。 また、今回紹介したダッシュボード自体もまだまだ開発中で、日々利用者様のフィードバックをいただきながら機能追加をしていっています。 見た目だけではない、具体的な改善アクションにつながるダッシュボードになるように一層意識していこうと思います。
We are hiring!
エムスリーでは、データを用いて価値を生み出したいエンジニアを広く募集中です。
社内外問わず、基盤を使ったシステムの開発や施策により世の中にインパクトを与える機会が多数ありますので、是非我こそは!という方はカジュアル面談、ご応募お待ちしています!