📌

dbt × BigQueryでCICDパイプラインを実装してみる

に公開

dbt CloudとBigQueryで実現するデータ開発のCI/CDパイプライン

dbt(data build tool)は、SQLによるデータ変換を効率化する強力なツールですが、その真の強みは、開発プロセスにソフトウェア開発の手法、特にテスト機構(CI/CDパイプライン)を組み込める点にあります。

しかし、自社ではCI/CDパイプラインを構築しておらず、開発時には気づかなかったエラーが本番環境で見つかるという状態に陥っていました。

そこで、社内でのCI/CDパイプライン構築を提案するため、まずは私用のdbtアカウントで簡単に実装方法を検証しました。


CI/CDとは何か? なぜデータ開発に必要なのか?

CI/CD(Continuous Integration / Continuous Delivery, 継続的インテグレーション/継続的デリバリー)とは、コードの変更を頻繁かつ自動的にビルド、テスト、およびデプロイすることで、開発の効率化と品質の向上を図るソフトウェア開発の手法です。

データ基盤の文脈においては、特に以下の2つのフェーズが重要です。

フェーズ 役割 データ開発における具体的な意味
CI (継続的インテグレーション) 開発者がプルリクエスト(PR)を作成するたびに、自動テストを実行し、問題を早期に検出する。 データモデルが正しく変換されるか、そしてデータの品質要件(NULLがないか、一意であるかなど)を満たしているかを自動で検証する。
CD (継続的デリバリー) テスト済みのコードを本番環境へ自動でリリースする。 CIテストを通過した信頼性の高いデータモデルのみを、手動操作なしでSnowflakeやBigQueryなどの本番データセットに反映し、利用者に提供する。

本番環境に反映する前に、エラーやデータ品質の問題に気づけるため、データエンジニアリングの領域で必須のプラクティスです。


前提とプロジェクト準備

■ 前提環境・準備

  • dbt: dbt Cloud
  • DWH: BigQuery
  • BigQuery内のデータセット:
    • prod: 本番データセット
    • dbt_(名前): 個人の開発用データセット(dbt Cloudのデフォルト設定)
  • サンプルデータ: dbt-tutorial.jaffle_shopのパブリックデータを使用。

以下の通り、超シンプルなモデル構成を採用しました。

以下の記事を参考に、dbtとBigQueryの接続、モデルの作成を行いました。
https://dev.classmethod.jp/articles/quickstart-for-dbt-cloud-and-bigquery/#toc-06-dbt-cloud

■ 環境の作成と分離

CI/CDを実装する上で、開発・テスト用の設定と、デプロイ用の設定に分けておくことが必要です。

私のdbtプランの制約上、プロジェクトは1つしか作成できないため、1つのプロジェクト内開発用デプロイ用の2つの環境(Environment)を作成することで対応します。


Development(開発用、デフォルト)とProduction(本番用、新規作成)

  • デフォルトのDevelopment環境を開発用として使用します。
  • 新たに作成するProduction環境を本番用(デプロイ用)とします。

BigQuery側で本番用データセット(例:prod)を作成した後、dbt Cloudの左側バーの Orchestration > Environments から、以下の設定でProduction環境を作成しました。


BigQueryへのConnection情報と、本番環境のデータセット(スキーマ)を指定


CI/CDジョブの作成

環境が整ったので、CIとCDの2つのジョブを作成します。

1. CIジョブの作成 (Continuous Integration)

Orchestration > Environments > + Create Job から 「Continuous Integration Job」 を選択します。これはプルリクエスト(PR)をトリガーとするジョブになります。あとは以下のようにジョブの作成を行います。


CIジョブの設定。Production環境を選択し、PRをトリガーとしている。

  • Environment: Development環境を選べなかったため、Production(本番環境)を選択しています。しかし、CIの結果はデフォルトでは一時的なスキーマに作成され、かつテストが終われば自動で削除されるため、本番環境のデータに影響はありません。

  • Execution settings: dbt build --select state:modified+ を採用しました。

    • --select state:modified+オプションによって、変更されたモデルとその子孫モデルのみを実行します。これにより、ジョブ実行時間が短縮され、BigQueryの使用料(処理スキャン量)も削減できます。
  • Compare changes against an environment (Deferral): Production環境を選択します。

    • CIテストをする際に、「比較対象となる直前の状態はどれか」を定義します。今回はproduction環境のジョブが最後に「成功」したときの状態を比較対象として使用します。これにより、変更のないテーブルについては、Production環境の既存のテーブルを参照する(Deferral: 据え置き)ことが可能になります。

2. CDジョブの作成 (Continuous Delivery)

CIジョブと同様に + Create Job から 「Merge Job」 を選択します。これはGitHub上でのマージをトリガーとして本番へのデプロイを行うジョブです。


CDジョブの設定。マージをトリガーとし、Production環境にデプロイする。

設定の考え方はCIジョブとほぼ同じですが、こちらはPRではなくマージをトリガーとします。


初回実行とManifestエラーの解決

2つのジョブの設定後、プルリクエスト、マージを行うと、以下のエラーメッセージが出てジョブがスキップされてしまいます。

This job is configured to use the manifest of another job's previous run, which could not be located.


Manifestファイルがないためジョブが実行できないエラー

これは、dbt build --select state:modified+ コマンドが、比較対象となる「前回成功した本番デプロイ時のManifestファイル」をdbt Cloud上にまだ見つけられないことが原因です。

解決策:CDジョブの手動実行

スキップを防ぐには、最初だけCDジョブをdbt Cloudの画面から手動で実行し、成功履歴(Manifestファイル)を作成する必要があります。

  1. 失敗したCDジョブ(CD / Production Deploy)を手動で再実行します。
  2. ジョブが成功すると、Production環境の成功履歴としてManifestファイルが作成され、dbt Cloud上に保存されます。


初回の手動実行により、Manifestファイルが生成され、本番データセットにモデルがデプロイされた。


パイプラインの動作検証

Manifestファイルの準備ができたので、実際にエラーを検出し、修正してデプロイするCI/CDのフローを検証します。

1. 依存関係エラーの埋め込み

stg_customers.sqlのカラム名を意図的に変更(first_nameという名前からf_nameに変更)し、依存するモデルに影響が出るようにします。

ローカルの開発環境でこのモデルだけを dbt run してもエラーにはなりませんが、依存している customers.sql では古いカラム名を参照し続けるため、全モデルに対して dbt run を実行するとエラーになります。

2. CIジョブによるエラー検出

上記の変更をプルリクエストすると、CIジョブが自動で動き、依存モデルのエラーを検出してくれます。


CIジョブが失敗し、customersモデルでのカラム参照エラーを指摘している。

3. 修正とCD成功

CIジョブのエラーを確認し、customers.sql のカラム名も修正して再度プルリクエストを更新します。

  1. customers.sql のカラム名を修正し、GitHubへプッシュ。
  2. CIジョブが再実行され、成功
  3. CI成功後、GitHubでマージを実行。
  4. CDジョブが自動実行され、成功

結果: CIパイプラインによって開発段階でエラーを検出し、修正してから本番環境へデプロイすることができました。これで無事、本番環境にエラーのない状態で、データモデルを反映することができました。



結び

dbt Cloudのジョブと環境設定を組み合わせることで、プロジェクト制限のある無料プランでも、安全で効率的なCI/CDパイプラインを簡単に構築できることが確認できました。

この検証結果をもとに、今後は社内での本格的なCI/CD導入を進め、データ品質と開発スピードの向上を目指します。

(本記事は一部生成AIによって文章の作成を行っております)

Discussion