
dbt Cloudのジョブをyamlで定義できるdbt-jobs-as-codeを試してみた
さがらです。
dbt Cloudではジョブという、dbtコマンドをスケジュール実行する機能が標準で備わっています。
このジョブですが、標準機能ではGUIベースで定義するしかありません。
そこで、dbt Labs社より提供されているdbt Cloudのジョブをyamlで定義できるOSSのツールであるdbt-jobs-as-codeを試してみたので、その内容を本記事でまとめてみます。
dbt-jobs-as-code
改めてdbt-jobs-as-codeですが、dbt Labs社の公式GitHubアカウントより提供されている、dbt Cloudのジョブをyamlで定義できるOSSのツールです。
単純にyamlでジョブを定義するだけでなく、Jinjaテンプレートを用いてproject_idとenvironment_idを動的に入力することで、1つのジョブ定義をStaging・Prodの両環境に適用させる、ということも可能です。
Terraformとの違い
dbt Cloudのジョブをコードで定義する方法として、Terraformもあります。
このTerraformとdbt-jobs-as-codeについての使い分けですが、公式Docからの引用と私の意見も加味して、以下のような使い分けになると思います。
- Terraform
- 用途:ジョブ以外の、Environmentやグループなど他のdbt Cloudのオブジェクトをコードで管理
- 使用ユーザー:インフラ・データ基盤全体を管理するレイヤーの方
- Terraformの開発・実行にはdbt Cloud外の環境が必要となるため、dbt Cloudだけを使う人とはレイヤーが異なる
- dbt-jobs-as-code
- 用途:dbt Cloud上からyamlを書いてジョブをコードで管理
- 使用ユーザー:dbt Cloud上で開発を行い、ジョブの設定もする方
- 一度GitHub Actionsを定義すれば、dbt CloudのIDE上でyamlを書いてmainブランチに反映させるだけでジョブが定義される
試してみた
実際にdbt-jobs-as-codeを用いたGitHub Actionsを定義し、dbt Cloudからyamlを書いてプルリクエストを送り、GitHub Actions経由でジョブの定義を行ってみます。
dbt Cloudのサービストークンの取得と、リポジトリにSecretとして登録
まず、dbt Cloudからサービストークンを取得して、リポジトリにDBT_API_KEY
という名称でSecretを登録します。(サービストークンですが、本ツールの仕様上DBT_API_KEY
という名称でSecret登録が必要です。詳細はこちらの内容をご覧ください。)
Permission setは、対象のdbtプロジェクトに対するJob Admin
があればOKです。
トークンが表示されたら、忘れずに控えておきましょう。
この後、対象のGitHubリポジトリでSecretとして登録しておきます。
GitHub Actionsの定義
続いて、GitHub Actionsのジョブを定義します。以下のリンク先においても、様々なパターンでGitHub Actionsのジョブ定義について言及があるため、参考になると思います。
dbt Cloudを開き、ルート階層から見て.github/workflows
という2つのフォルダを作成します。
GitHub Actionsのジョブを定義するためのファイルを作成します。ファイル名は何でもよいのですが、dbt_jobs_cicd.yml
というファイル名で作成します。
ファイルの内容としては、以下の内容で定義します。
name: CI/CD for dbt Cloud Jobs
on:
pull_request:
branches:
- main
paths:
- 'jobs/**' # jobsディレクトリ配下の変更時のみ実行
push:
branches:
- main
paths:
- 'jobs/**'
jobs:
dbt-jobs-as-code:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.12"
- name: Install dbt-jobs-as-code
run: pip install dbt-jobs-as-code
- name: Run 'plan' on Pull Request
if: github.event_name == 'pull_request'
run: dbt-jobs-as-code plan jobs/jobs.yml
env:
DBT_API_KEY: "${{ secrets.DBT_API_KEY }}"
- name: Run 'sync' on Merge to main
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: dbt-jobs-as-code sync jobs/jobs.yml
env:
DBT_API_KEY: "${{ secrets.DBT_API_KEY }}"
この定義後、一度プルリクエスト発行~mainブランチへマージしておきます。
yamlでジョブを定義し、dbt Cloudへ反映
次に、dbt-jobs-as-codeの仕様に併せて、yamlでジョブを定義します。
まず、ルート階層から見てjobs
というフォルダを作成します。
このあと、jobs
フォルダ内でjobs.yml
というファイルを作成します。(フォルダ名とファイル名はなんでもよいのですが、先に定義したGitHub Actionsの参照先と合わせています。)
内容は以下の通りとします。注意点として、account_id
、project_id
、environment_id
は皆様の環境に合わせて修正ください。(対象のEnvironmentを開き、URL欄に書かれた数字が各idに該当します。)
jobs:
# ジョブのユニークなID(任意)
weekly_build_job:
# ご自身のdbt Cloudアカウント情報に書き換えてください
account_id: 12345
project_id: 67890
environment_id: 11223
# dbt Cloudの画面上で表示されるジョブ名
name: "毎週月曜5時build"
# 実行するコマンド
execute_steps:
- "dbt build"
# スケジュール設定
schedule:
# UTCで指定します。「毎週日曜の20:00」=「日本時間の毎週月曜の05:00」
cron: "0 20 * * 0"
# トリガー設定
triggers:
github_webhook: false
git_provider_webhook: false
schedule: true # スケジュール実行を有効化
# その他の設定
settings:
threads: 4
target_name: production
state: 1 # 1: active, 2: deleted
generate_docs: true
run_generate_sources: true
この上で、コミットしてプルリクエストを発行します。
すると、dbt-jobs-as-code plan jobs/jobs.yml
が実行され、「sync
を実行すると、新しいweekly_build_job
を作るよ」という内容が表示されます。
この後にマージすると、dbt-jobs-as-code sync jobs/jobs.yml
が実行されます。
dbt Cloudのジョブ管理画面から確認すると、指定した内容でジョブが作成されていました!ジョブ名ですが、末尾に[[ ]]
で挟んで、yaml上のjobのidが追記される仕様となっています。
ジョブの定義を削除したい場合
最後に、ジョブの定義を削除したい場合の操作について確認します。
ジョブの定義を削除
下図のように、既にdbt Cloudに反映済みジョブの定義を削除した場合でも、ジョブの削除は可能です。(ただし、後述の「注意点」でも述べていますが、1つ以上ジョブの定義がされていないとエラーになるためご注意ください。)
- weekly_build_job:既にdbt Cloudに反映済みだが、定義を削除(コメントアウト)する
- weekly_build_job_2:新規作成
この状態でプルリクエストを発行してdbt-jobs-as-code plan jobs/jobs.yml
が実行されると、下図のように表示されます。yamlから記載をなくしたweekly_build_jobについて、DELETE
となっていますね。
state: 2
とする
ジョブの定義の中でstate
というパラメータがあり、これをstate: 2
とすることで、対象のジョブが削除される仕様となっています。
この状態でプルリクエストを発行してdbt-jobs-as-code plan jobs/jobs.yml
が実行されると、下図のように表示されます。weekly_build_jobについて、UPDATE
となっていますね。
この状態でプルリクエストをマージして、dbt-jobs-as-code sync jobs/jobs.yml
が実行されると、下図のように表示されます。(私の場合はなぜかエラーとなっていますが…ジョブの定義が1つもない状態となったためと推測しています。)
この後にdbt Cloudで対象のdbtプロジェクトを見ると、ジョブが削除されていました!
注意点
jobs.yml
に対して以下の変更を行うと、エラーとなったり正しく検知されないため、ご注意ください!!
jobs.yml
の内容から定義したジョブに関する記述を全て削除(コメントアウト)してjobs:
だけが残るパターン
jobs.yml
のファイルの内容全てを削除(コメントアウト)するパターン
参考:CI Jobの設定
dbt Cloud特有のCI Jobの設定についても試そうとしたのですが、上手くいかなかったです…
ドキュメントにも各パラメータの説明がないと感じたので、このあたりはドキュメントや機能改善に期待したいところですね!
最後に
dbt Labs社より提供されているdbt Cloudのジョブをyamlで定義できるOSSのツールであるdbt-jobs-as-codeを試してみました。
dbtのジョブは数が多くなってくるとGUIベースの管理が難しくなるところもあると思いますので、yamlで定義したい際にはdbt-jobs-as-codeが役立つと思います!現状、CI JobとMerge Job以外の通常のDeploy Jobならば利用できるかと思います。
ぜひご活用ください。