🍊

dbt docs を GitHub Actions で GCS にホストする

2024/08/25に公開

はじめに

  • 対象者 : Bigqueryを使用するdbt core ユーザー
  • dbt docsのホスティングは、社内公開を目的にCloud Runなどを使用する記事が多いですが、まだそのフェーズまで進んでいないケースが多く、Cloud Runを使うのは少しオーバーキルかもしれません。社内公開はまだ先、権限管理大変、Terraform書くのも大変、、、
  • 今回紹介する方法は、データチームのみ(Google Cloudにアクセスできる人のみ)が閲覧できれば良いスモールスタート的なフェーズでdbt docsの運用を楽にします

やりたいこと

下記の記事で紹介されていることをGitHub Actionsを用いて自動化します。

# 目的
ドキュメントを確認するたびにdbt docs serveでサーバを稼働させる手間を省くため、
dbt docs serveを利用せずにGCSに静的htmlを配置してホストします。

https://zenn.dev/persona/articles/d191d285062997

記事の中では静的htmlのスクリプトが紹介されていますが、dbt 1.7.0からdbt docs generate --staticのコマンドで同様の処理ができる機能が追加されました

dbt docs generate --static

実行するとtargetフォルダにstatic_index.htmlの名前で静的htmlを出力できる様になりました

https://github.com/dbt-labs/dbt-core/issues/8614

  • 紹介されたスクリプト(参考までに)

https://github.com/aibazhang/dbt-metadata-management/blob/main/generate_static_html.py

手順

  1. 静的htmlを配置するGCS(Cloud Storage)の作成
  2. GitHub ActionsでGCSとBigqueryにアクセスする用のサービスアカウント作成
  3. サービスアカウントキー発行して、Actions secretsに登録
  4. GitHub ActionsのコードをGitHubにあげる

1. 静的htmlを配置するGCS(Cloud Storage)の作成

2. GitHub ActionsでGCSとBigqueryにアクセスする用のサービスアカウント作成


ロールは、下記で設定します。

  • BigQuery ジョブユーザー : ジョブを実行するためのアクセス権
  • BigQuery データ閲覧者 : データセットとそのすべてのコンテンツを表示するためのアクセス権
    • 静的html生成するだけなので最小限の権限にします
  • Storage オブジェクト管理者 : オブジェクトの一覧表示、作成、表示、削除など、オブジェクトのすべてを管理できる権限を付与します。
脱線しますが、dbtのドキュメントでQuickstartとそうではないページの必要ロールがちょっと違います(謎)

From the Select a role dropdown, choose BigQuery Job User and BigQuery Data Editor roles and click Continue

https://docs.getdbt.com/guides/bigquery?step=4

BigQuery's permission model is dissimilar from more conventional databases like Snowflake and Redshift. The following permissions are required for dbt user accounts:
- BigQuery Data Editor
- BigQuery User

https://docs.getdbt.com/docs/core/connect-data-platform/bigquery-setup#required-permissions

3. サービスアカウントキー発行して、Actions secretsに登録

[Google Cloud]新しい鍵の作成でJSONファイルがダウンロードされます。

[GitHub]SettingsSecrets and variablesActions
GCP_SA_KEYの名前で、JSONファイルの中身を登録する

VariablesにBigqueryの対象プロジェクトIDを登録。GitHub Actionsの実装によっては対象データセットIDを登録しても良いと思う。

4. GitHub ActionsのコードをGitHubにあげる

/
.github
├─ setting
│  └─ profiles.yml
└─ workflows
   └─ deploy_dbt_docs.yml

supported by : https://zenn.dev/praha/articles/b2e225ae091ae3

  • devとprod分けてない構成になっています
  • GitHub Actionsの実装によっては対象データセットIDをActions variablesに登録しても良いと思う
setting/profiles.yml
dbt_project:
  outputs:
    dev:
      dataset: dbt
      job_execution_timeout_seconds: 300
      job_retries: 1
      keyfile: "{{ env_var('DBT_GOOGLE_KEYFILE') }}"
      location: asia-northeast1
      method: service-account
      priority: interactive
      project: "{{ env_var('DBT_GOOGLE_PROJECT') }}"
      threads: 16
      type: bigquery
  target: dev
  • 下記を適宜書き直して使ってください
    • dbtプロジェクトフォルダ名
    • 作成したGCS名
workflows/deploy_dbt_docs.yml
name: Deploy dbt docs to GCS
run-name: Run by @${{ github.actor }} - ${{ github.workflow }}

on:
  push:
    branches:
      - main
    paths:
      - 'dbtプロジェクトフォルダ名/**'
  workflow_dispatch: # 手動トリガーの追加

env:
  DBT_PROFILES_DIR: ../.github/setting
  DBT_GOOGLE_PROJECT: ${{ vars.DBT_GOOGLE_PROJECT }}
  DBT_GOOGLE_KEYFILE: /tmp/dbt-service-account.json

jobs:
  deploy:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    
    steps:
    - uses: actions/checkout@v4

    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.12'

    - name: Authenticate using service account
      run: 'echo "$KEYFILE" > /tmp/dbt-service-account.json'
      shell: bash
      env:
        KEYFILE: ${{secrets.GCP_SA_KEY}}
    
    - name: Install dependencies
      run: |
        pip install dbt-bigquery==1.8

    - name: Generate dbt docs
      run: |
        cd dbt_project
        dbt deps  --target dev
        dbt debug  --target dev
        dbt docs generate --static  --target dev
      
    - name: Rename static_index.html to index.html
      run: mv dbtプロジェクトフォルダ名/target/static_index.html dbtプロジェクトフォルダ名/target/index.html

    - name: Authenticate to Google Cloud
      uses: google-github-actions/auth@v2
      with:
        credentials_json: ${{secrets.GCP_SA_KEY}}

    - name: Upload to GCS
      uses: google-github-actions/upload-cloud-storage@v2
      with:
        path: dbtプロジェクトフォルダ名/target/index.html
        destination: 作成したGCS名/
        parent: false
        process_gcloudignore: false

    - name: Delete Credentials
      if: always() # ワークフローの他のステップが失敗した場合でも、このステップが確実に実行
      run: 'rm /tmp/dbt-service-account.json'

profiles.ymlがもっとリッチな場合は、下記の記事を参考にしてください。ここら辺はGitHub Actionsでdbt buildする記事とか探せば良いと思います。
https://dev.classmethod.jp/articles/dbt-core-run-via-github-actions/
https://medium.com/inthepipeline/how-to-run-dbt-with-bigquery-in-github-actions-97ccb1761f4b

実行方法

  • プルリクエストでmainにマージ -> dbtプロジェクトフォルダのファイルが変更された
    上記の条件でジョブ実行されます

  • GCS内の静的htmlが更新されます
  • 認証済みURLを共有すれば、権限を付与されているユーザーのみが、このリンクを使用してオブジェクトにアクセスできる状態になります!
[おまけ] dbt docs のトップページの編集

[おまけ] dbt docs のトップページの編集

models配下にoverview.mdというマークダウンファイルを作成し、以下内容を入れます。

models/overview.md
{% docs __overview__ %}
### Welcome!
dbtプロジェクトの自動生成ドキュメントへようこそ!
### Navigation
ウィンドウの左側にあるプロジェクトとデータベースのナビゲーションタブを使って、プロジェクト内のモデルを調べることができます。
#### Project Tab
プロジェクトタブはdbtプロジェクトのディレクトリ構造を反映しています。このタブでは、dbtプロジェクトで定義されたすべてのモデル、およびdbtパッケージからインポートされたモデルを見ることができます。
#### Database Tab
データベースタブにもモデルが表示されますが、よりデータベースエクスプローラーに近い形式で 表示されます。このビューには、データベーススキーマにグループ化されたリレーション(テーブルとビュー)が表示されます。エフェメラルモデルはデータベースに存在しないため、このインターフェースには表示されないことに注意してください。
### グラフ探索
ページの右下にある青いアイコンをクリックすると、モデルの系統グラフを見ることができます。

モデルのページでは、探索中のモデルの直接の親と子が表示されます。この血統ペインの右上にある「展開」ボタンをクリックすると、現在調べているモデルを構築するために使用された、あるいは構築されたすべてのモデルを見ることができます。

一度展開されると、`--select``--exclude` のモデル選択構文を使って、グラフ内のモデルをフィルタリングすることができるようになります。モデル選択の詳細については、dbtの[ドキュメント](https://docs.getdbt.com/reference/node-selection/syntax)を参照してください。

また、モデルを右クリックすることで、グラフをインタラクティブにフィルタリングしたり、探索したりすることもできます。

------
### More information
- [What is dbt](https://docs.getdbt.com/docs/introduction)?
- Read the [dbt viewpoint](https://docs.getdbt.com/docs/viewpoint)
- [Installation](https://docs.getdbt.com/docs/installation)
- Join the [dbt Community](https://www.getdbt.com/community/) for questions and discussion
{% enddocs %}

https://zenn.dev/kyami/articles/f9cd03daccc6af#2.トップページの編集

おわりに

dbt core ユーザーはdbt docsをどこに置くか問題があります。
その中で一番カロリーが低く、dbt docsを運用する方法を目指しました。

参考

https://zenn.dev/persona/articles/d191d285062997
https://github.com/dbt-labs/dbt-core/issues/8614
https://github.com/astronomer/astronomer-cosmos/issues/746
https://medium.com/inthepipeline/how-to-run-dbt-with-bigquery-in-github-actions-97ccb1761f4b
https://dev.classmethod.jp/articles/dbt-core-run-via-github-actions/
https://zenn.dev/kyami/articles/f9cd03daccc6af#2.トップページの編集

Discussion