GitHub Actionsを使ってSnowflakeのデータへdbtを実行する方法

## はじめに

データエンジニアリングや分析基盤の分野では、dbt（Data Build Tool）が重要な役割を果たしています。dbtは、データのトランスフォーメーション（変換）をシンプルかつ効率的に行うための強力なツールで、多くの企業やデータエンジニアが活用しています。
しかし、日々のデータ更新を手動で実行するのは手間がかかり、ミスの原因にもなります。そこで、CI/CDパイプラインツールであるGitHub Actionsを活用することで、dbtの実行を自動化し、信頼性と再現性のあるデータトランスフォーメーションを実現できます。
本記事では、GitHub Actionsを用いて、Snowflake上でdbtを定期的に自動実行する方法について解説します。



## プロジェクトのディレクトリ構造
まず、GitHubリポジトリのディレクトリ構造を確認しておきましょう。以下のような構成を想定しています。ローカルで開発しリポジトリはすでに完成しているものとします。
```
├── .dbt
│   ├── profiles.yml  # プロファイル設定ファイル
├── .github
│   └── workflows
│       └── dbt_run.yml  # GitHub Actionsワークフロー
├── date_change  # dbtプロジェクトディレクトリ
│   ├── dbt_project.yml
│   └── models
├── README.md
└── dbt_project.yml
```

- `.dbt/profiles.yml`は、dbtが接続に必要とするSnowflakeのプロファイル設定を含むファイルです。
- `.github/workflows/dbt_run.yml`には、GitHub Actionsのワークフロー設定を記述します。
- `date_change`フォルダには、dbtプロジェクトの`dbt_project.yml`と`models`ディレクトリが含まれています。


## GitHub Secretsの設定
セキュリティの観点から、パスワードやアカウント情報は直接コードに含めず、GitHub Secretsに格納します。以下の情報をGitHub Secretsに設定しておきましょう。

1. リポジトリのページから **Settings > Secrets and variables > Actions** に移動します。

2. **New repository secret** をクリックし、以下の情報を登録します。

| Secret 名           | 値（例）                  |
|---------------------|---------------------------|
| `SNOWFLAKE_ACCOUNT` | `wh.us-central1.aws` |
| `SNOWFLAKE_DATABASE`| `TEST_DB`                    |
| `SNOWFLAKE_PASSWORD`| `PASSWORD`       |
| `SNOWFLAKE_ROLE`    | `ACCOUNTADMIN`            |
| `SNOWFLAKE_SCHEMA`  | `TEST_SC`                    |
| `SNOWFLAKE_USER`    | `TRANSFORM`           |
| `SNOWFLAKE_WAREHOUSE` | `TEST_WH`             |

これで、プロファイル設定ファイル`profiles.yml`の中でこれらの情報を使用できるようになります。
![スクリーンショット 2024-10-31 14.57.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/92a6aaa0-d16f-816c-a037-f7ab86911eb1.png)



## profiles.ymlの設定
GitHub Actions内で`profiles.yml`を生成し、dbtがSnowflakeに接続できるようにします。以下のコードを`dbt_run.yml`内で実行して`profiles.yml`を作成します。

```yaml
date_change:
  outputs:
    dev:
      account: '${{ secrets.SNOWFLAKE_ACCOUNT }}'
      database: '${{ secrets.SNOWFLAKE_DATABASE }}'
      password: '${{ secrets.SNOWFLAKE_PASSWORD }}'
      role: '${{ secrets.SNOWFLAKE_ROLE }}'
      schema: '${{ secrets.SNOWFLAKE_SCHEMA }}'
      threads: 1
      type: snowflake
      user: '${{ secrets.SNOWFLAKE_USER }}'
      warehouse: '${{ secrets.SNOWFLAKE_WAREHOUSE }}'
  target: dev
```

ここでは、GitHub Secretsから値を読み込み、接続情報を設定しています。Snowflakeアカウント情報やユーザー、ロールなど、dbtがSnowflakeに接続するために必要な情報がここに含まれています。


## GitHub Actionsのワークフロー設定
続いて、`.github/workflows/dbt_run.yml`にGitHub Actionsの設定を記述します。この設定により、dbtが自動で実行されるようになります。

```yaml
name: Run dbt Project


on:
  push:
    branches:
      - main
  workflow_dispatch:
  
#定期実行を設定する場合
#on:
#  push:
#    branches:
#      - main
#  workflow_dispatch:
#  schedule:
#    - cron: '0 9 * * *'  # 例)毎日朝9時に実行

jobs:
  dbt-run:
    runs-on: ubuntu-latest

    steps:
      - name: Check out repository
        uses: actions/checkout@v2

      - name: Set up Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.8'

      - name: Install dbt dependencies
        run: |
          python -m pip install --upgrade pip
          pip install dbt-core dbt-snowflake

      - name: Configure dbt profile for Snowflake
        run: |
          mkdir -p ~/.dbt
          echo "
          date_change:
            outputs:
              dev:
                account: '${{ secrets.SNOWFLAKE_ACCOUNT }}'
                database: '${{ secrets.SNOWFLAKE_DATABASE }}'
                password: '${{ secrets.SNOWFLAKE_PASSWORD }}'
                role: '${{ secrets.SNOWFLAKE_ROLE }}'
                schema: '${{ secrets.SNOWFLAKE_SCHEMA }}'
                threads: 1
                type: snowflake
                user: '${{ secrets.SNOWFLAKE_USER }}'
                warehouse: '${{ secrets.SNOWFLAKE_WAREHOUSE }}'
            target: dev
          " > ~/.dbt/profiles.yml

      - name: Run dbt
        working-directory: ./date_change  # dbt_project.ymlがあるディレクトリを指定
        run: dbt run
```

#### 各ステップの説明
- **Check out repository**: リポジトリの内容をGitHub Actionsの環境にチェックアウトします。
- **Set up Python**: dbtがPythonで実行されるため、Python環境をセットアップします。
- **Install dbt dependencies**: dbtとdbt-snowflakeをインストールします。
- **Configure dbt profile for Snowflake**: `profiles.yml`を動的に生成し、GitHub SecretsからSnowflakeの接続情報を読み込みます。
- **Run dbt**: `dbt run`コマンドを実行し、dbtプロジェクトを実行します。

これによりmainブランチに対して変更がコミットされると自動的にdbt runが走ります。以下が成功画面です。

![スクリーンショット 2024-10-31 14.48.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/7a35b0e2-e23a-be18-d57e-6976fc1471da.png)


## 定期実行の設定
上記のコード内で、以下の部分が毎朝9時に自動実行するための設定です。

```yaml
schedule:
  - cron: '0 9 * * *'  # 毎日朝9時に実行
```

この設定では、cron構文を使用しています。`0 9 * * *`は「毎日9時0分」にワークフローを起動するという意味です。`cron`構文をカスタマイズすることで、好きなタイミングでの実行を設定できます。例えば、毎週月曜日の9時に実行したい場合は、`cron: '0 9 * * 1'`と指定します。


## トラブルシューティング
### よくあるエラーと対処法

1. **No dbt_project.yml found**
   - `working-directory`の指定が正しくないと発生します。dbtプロジェクトの`dbt_project.yml`が含まれるディレクトリを指定してください。

2. **Could not find profile**
   - `profiles.yml`内で指定したプロファイル名とdbtプロジェクトが参照しているプロファイル名が一致しているか確認します。

3. **Secretsの設定ミス**
   - Secretsが正しく設定されていないと、接続情報が欠落してエラーが発生します。GitHub Secretsのスペルや設定内容を再確認してください。


## まとめ
GitHub Actionsを利用したdbtの自動化により、日々のデータトランスフォーメーションが効率化され、人的エラーの削減につながります。スケジュール設定により、朝一番でデータが最新の状態に整えられるため、より迅速な意思決定が可能になります。今回の設定を基に、さらに`dbt test`を追加することで、データ品質のチェックも自動化できるなど、CI/CDパイプラインの強化も期待できます。今後のプロジェクトでdbtとGitHub Actionsを活用する際の参考になれば幸いです。