Cloud Buildで実行するdbtプロジェクト
dbtの実行にCloud Buildを用いたので、その備忘録をここに残します。同じことを考えている方と、未来の自分の助けになれbと思います。
BigQueryにあるデータを処理してBigQuery(以下BQ)に格納することを前提として話を進めていきます。
なぜCloud Buildか
「dbt Cloud使えばいいじゃない」という意見もあると思うので色々考えたりしたことを残しておきます。
なぜdbt Cloud使わなかったの?
- 正直使いたかった
- dbt Cloudは基本的にBQのデータを保持せず、BQにジョブを投げるだけとのことだったので、顧客データをGCPの外に出すということもなく、結構良さそうだった
- でもdbt Cloudに「BigQuery管理者」の権限を渡さなきゃいけないところが自分としては看過できなかった
- ここは会社のフェーズ感、データ変換のスピード感の必要せ、DWHのプロジェクト管理の仕方などで受け入れられる部分、受け入れられない部分があると思います
- 弊社の場合はプロダクトにも用いるデータセットと、DWHのデータセットが同じプロジェクトで管理されているので、最悪何かやっちまうとプロダクト影響が出てしまうと判断し、この権限をdbt Cloudに持たせるのはやめようと判断しました
- 弊社GCPに詳しい人が多いので他のサービスとの組み合わせとか、IAMで適切に権限管理するとかそっちの方が向いているなと思ったのもあります
- ゆくゆくはdbtのプロジェクトにアナリティクスエンジニアやデータエンジニアだけでなく、プロダクト開発に携わるエンジニアにも参加してもらえたらスケールしていくなと思っているため
- プルリクを気軽に出せる環境を作っておけたらいろんな人に参加してもらえるなと思っています、データエンジニアが頑張り続けるとか、データエンジニアを採用しまくるよりはそっちの方が現実的と思いまして
なぜCloud Buildか
- Cloud Buildは今描いている理想の終着点ではない
- 理想としてはCloud Composerに乗せて、失敗した処理だけを行えるようにしたい
- 技術的に可能なのかはまだ把握できていません
- Cloud Composerに関しても、Airflowに関しても社内に知見がなく、ミニマムな要件(dbtでBQのテーブルを参照して作る)を達成するためにはCloud Buildでいけそうとなった
- Cloud Buildは結構社内で使われています
- まずはCloud Buildでキックできればそれでいい、失敗処理はできなくてもいいとしています
以上の理由でdbt + Cloud Buildで始めました。
これは現時点で自分のいる環境でのベストプランなので数ヶ月後は「dbt Cloud最高〜!」って言ってるかもしれませんが、裏切られた気持ちにならないでください。
やっていく
紹介しているやり方はこちらの記事を僕なりに解釈してアレンジしたものになります。
とても参考にさせていただきました。
dbtプロジェクトの作成
デモのためにdbt projectを新しく作ります。
dbt init
作成したものに必要なものを加えていくことにします。
gcloudの設定や、ご自身のGCPのプロジェクトの情報などに問題がない場合、
dbt debug
が問題なく通ることを確認して次に進んでください。
profiles.ymlの追加
Cloud Build上では、
dbt run --target ${_DBT_TARGET} --profiles-dir .
というようにコマンドを叩くようにしていきます。
dbtは--profiles-dir
オプションなしの場合~/.dbt
配下のprofiles.ymlを見にいきますが、profiles.ymlもリポジトリで管理してCloud Buildから見れるようにする必要があるのでdbt_project.ymlと同じ階層にprofiles.ymlを追加します。
cloud_build_dbt:
target: dev
outputs:
prod:
type: bigquery
method: oauth
project: 自分のプロジェクト名を入れてね
dataset: production
threads: 1
timeout_seconds: 300
priority: interactive
location: asia-northeast1
retries: 1
cloudbuild.yamlの追加
Cloud Buildでどのような処理を行うかの設定を追加する必要があります
steps:
- id: '1 Run dbt'
name: 'fishtownanalytics/dbt:${_DBT_VERSION}'
entrypoint: 'bash'
args:
- '-c'
- |-
echo "==========================================================="
pwd
echo "==========================================================="
dbt deps --profiles-dir .
if [[ $? == 1 ]]; then
echo 'dbt deps is faild'
exit 1
fi
dbt debug --target ${_DBT_TARGET} --profiles-dir .
if [[ $? == 1 ]]; then
echo 'dbt debug is faild'
exit 1
fi
pwd
ls
dbt run --target ${_DBT_TARGET} --profiles-dir .
if [[ $? == 1 ]]; then
echo 'dbt run is faild'
exit 1
fi
dbt test --data --target ${_DBT_TARGET} --profiles-dir .
if [[ $? == 1 ]]; then
echo 'dbt test is faild'
exit 1
fi
options:
logging: CLOUD_LOGGING_ONLY
timeout: 1200s
tags: ['dbt']
substitutions:
_DBT_VERSION: '1.0.0'
_DBT_TARGET: 'prod'
ちょっとだけ解説します。
- dbtのdockerイメージがあるので、それを元にさせてもらっています。
_DBT_VERSION
は任意のものが使えるわけではなく、dockerイメージがサポートしてくれている必要があるので注意してください - 最初にpwdをしているのは、dbt_project.ymlがあるディレクトリに移動する必要があるためです
- このプロジェクトでは特段移動する必要はありませんが、リポジトリ直下にdbt_project.ymlがない場合は、あるところまでcdしてあげてください
- あとはザーッと実行しています
- Cloud BuildはデフォルトでCloud Storageにビルドログを保存しようとするのですが、Cloud Loggingだけでいいやと思ってそのように指定しています(参考)
- Cloud Storageの権限まで持ちたくなかったのでこうしています
サービスアカウントの設定
Cloud Buildに何をさせてあげるかの設定をします。
サービスアカウントを作成して、以下の権限をつけてあげます。(必要に応じて増やしてください)
クエリする、データセットを作る、テーブルを作る、ログを書き込むという権限のためにこのような設定にしています。(つけすぎだろってツッコミあったら教えてください🙇)
Cloud Buildの作成
リポジトリとの接続
GitHubのリポジトリと紐づける必要がありますので必要な情報を入力してあげてください。
その他設定
設定はこんな感じにしています。CI/CDとしての機能は必要に応じてつけてください。僕は手動呼び出しを使っています。Cloud Buildは1日120分を超えた使用に対して課金が発生するので、そこだけ気をつけるといいかなと思います。(参考)
サービスアカウントの入力
最後に先ほど設定したサービスアカウントを入力してください。
実行
開発中は必要に応じてブランチを選択すると任意のブランチを対象にできます。
このAPI有効にしろって言われるかもしれません、有効にしてください。
productionデータセットとテーブル、ビューができていれば成功です!
最後に
Cloud Buildがdbtを使う際のオプションの一つになればと思います。
そして何より未来の自分がこれ書いてあると助かります。
GitHubのリポジトリも載せておきます、profiles.ymlを書き換えてお使いください。
Discussion