まずはじめに整備しておきたい開発環境
以前の記事で dbt project on Snowflake を運用にのせるための CI / CD パイプライン構築について触れました。今回の記事もパイプラインの一部に触れつつ、運用に向けて整備した開発環境について記載しようと思います。( ※ dbt project on Snowflake 自体の説明は割愛しています)
ローカル環境から Snowflake への接続
dbt project on Snowflake を利用しているかどうかに関わらず、Snowflake を運用していると、手元でコーディングやテストをするのはもちろん、わざわざ Snowsight にログインせずともローカル環境の IDE からクエリを実行したくなります。特に最近では Cursor などを使った AI 中心のコーディングが当たり前になっており、ローカル環境の整備は開発スピードに直結します。
そこで、ローカル環境を
-
接続情報:
config.tomlまたはconnection.tomlで管理 -
認証方式: 秘密鍵認証 (Key Pair Authentication)
-
ツール: VSnowflake Extension for Visual Studio Code & Snowflake CLI
とすることで、チームメンバー全員が各人のアカウントでかつ、セキュアに Snowflake を操作できるようにしました。
認証については、MFA (二要素認証) が必須 となっているパスワード認証ではなく秘密鍵認証が便利ですね。これで煩わしいパスワードの入力を省略できます。
ローカル環境から dbt project object を操作する
実際の運用が始まるとあまりなさそうですが、ローカル環境からも Snowflake 上の複数環境に構築されている dbt project object を操作できるようにしておきたいです。弊社の運用では、本番環境と検証環境を同じ Snowflake アカウント内の異なるデータベースで分離しています。
dbt project on Snowflake を運用するにあっては profiles.yml の管理はできるだけシンプルにしたいです。ここは一般的な手法を用いて、profiles.yml は 1 つのファイルにまとめ、dbt run 時に --target オプションで環境を切り分けるように設計することとしました。これで snow dbt deploy {DBT_PROJECT_NAME} --default-target {TARGET_NAME} や snow dbt execute {DBT_PROJECT_NAME} run --target {TARGET_NAME} でローカル環境から本番環境・検証環境を操作できます。
パイプラインから dbt project object を操作する
いざ運用が始まると、パイプラインからの操作がメインです。ローカル環境からの操作性を失わずに、かつローカル環境とは異なる認証方式 (OIDC) で操作できるような設計としなければいけません。
これらを考慮し profiles.yml はこのように完成しました。
dbt_project: target: staging outputs: staging: type: snowflake account: ACCOUNT_ID # 空またはダミーでよいがAccountは共通のため記載 user: # 空またはダミー role: ROLE_NAME warehouse: # 空またはダミー database: STG_DATABASE_NAME schema: SCHEMA_NAME production: type: snowflake account: ACCOUNT_ID # 空またはダミーでよいがAccountは共通のため記載 user: # 空またはダミー role: ROLE_NAME warehouse: # 空またはダミー database: PROD_DATABASE_NAME schema: SCHEMA_NAME
ポイントは全環境で共通となる最低限の項目しか記載しないことです。公式ドキュメントを見ると、以下のように Database / Role / Schema / Type が必須と記載されています。
profiles.yml: A dbt connection profile definition referenced in dbt_project.yml. profiles.yaml must define the database, role, schema, and type.
他の項目は snow コマンド実行時にオプションで記載するか config.toml または connection.toml を作成してあげることで、パイプライン上からも本番環境・検証環境を操作できます。
オプションで指定する場合には、GitHub Actions に
snow dbt deploy DBT_PROJECT_NAME \ --account ${{ env.SNOWFLAKE_ACCOUNT }} \ --user ${{ env.SNOWFLAKE_USER }} \ --role ${{ env.SNOWFLAKE_ROLE }} \ --warehouse ${{ env.SNOWFLAKE_WAREHOUSE }} \ --authenticator ${{ env.SNOWFLAKE_AUTHENTICATOR }} \ --workload-identity-provider ${{ env.SNOWFLAKE_WORKLOAD_IDENTITY_PROVIDER }} \ --source SOURCE_DIR \ --default-target TARGET_NAME \ --temporary-connection \ --force
のように記載することになります。config.toml または connection.toml を作成しない場合は --temporary-connection が必要です。
注意点
完成してみればなんのことはないのですが、ここに辿り着くまでにいくつか苦労した点があります🤢
本番環境と検証環境を切り替えれない
snow dbt deploy では --default-target オプションを使って本番環境と検証環境へのデプロイを切り替えています。はじめSnow CLI v3.12 で動かしていたためこのオプションが使用できませんでした。v3.13 以降 (2025/12/26 時点では v3.14 が最新) でないと使用できません。
環境変数を読み込めない
dbt では profiles.yml に {{ env_var('SNOWFLAKE_ACCOUNT') }} のように記載すると環境変数を読み込ませることができます。これを使って当初、
dbt_project: target: staging outputs: staging: type: snowflake account: ACCOUNT_ID user: "{{ env_var('SNOWFLAKE_USER', 'PIPELINE_USER_NAME') }}" role: "{{ env_var('SNOWFLAKE_ROLE', 'PIPELINE_ROLE_NAME') }}" warehouse: "{{ env_var('SNOWFLAKE_WAREHOUSE', 'PIPELINE_WAREHOUSE_NAME') }}" database: STG_DATABASE_NAME schema: SCHEMA_NAME production: type: snowflake account: ACCOUNT_ID user: "{{ env_var('SNOWFLAKE_USER', 'PIPELINE_USER_NAME') }}" role: "{{ env_var('SNOWFLAKE_ROLE', 'PIPELINE_ROLE_NAME') }}" warehouse: "{{ env_var('SNOWFLAKE_WAREHOUSE', 'PIPELINE_WAREHOUSE_NAME') }}" database: PROD_DATABASE_NAME schema: SCHEMA_NAME
のように、GitHub Actions で使用する値をデフォルト値とし、ローカル環境では環境変数で上書きするよう設計していましたが、snow dbt コマンドからは env を解決できず、そのまま "{{ env_var('SNOWFLAKE_USER', 'PIPELINE_USER_NAME') }}" が文字列として扱われてしまいました。
env_var にも対応されれば (近いうちに対応予定と耳にしています) 長いオプションを書かなくてもよくなりコードがスッキリしますね 👏
オプションの順序
パイプラインでは snow dbt deploy の後に snow dbt execute で dbt run や dbt test を実行しています。
この時、snow dbt deploy と同様に
snow dbt execute DBT_PROJECT_NAME run \ --account ${{ env.SNOWFLAKE_ACCOUNT }} \ --user ${{ env.SNOWFLAKE_USER }} \ --role ${{ env.SNOWFLAKE_ROLE }} \ --warehouse ${{ env.SNOWFLAKE_WAREHOUSE }} \ --authenticator ${{ env.SNOWFLAKE_AUTHENTICATOR }} \ --workload-identity-provider ${{ env.SNOWFLAKE_WORKLOAD_IDENTITY_PROVIDER }} \ --source SOURCE_DIR \ --target TARGET_NAME \ --temporary-connection
とオプションを記載するとエラーになります。
snow dbt execute では DBT_PROJECT_NAME 以降のパラメーターを dbt へ丸投げする仕様となっているようで、
snow dbt execute \ --account ${{ env.SNOWFLAKE_ACCOUNT }} \ --user ${{ env.SNOWFLAKE_USER }} \ --role ${{ env.SNOWFLAKE_ROLE }} \ --warehouse ${{ env.SNOWFLAKE_WAREHOUSE }} \ --authenticator ${{ env.SNOWFLAKE_AUTHENTICATOR }} \ --workload-identity-provider ${{ env.SNOWFLAKE_WORKLOAD_IDENTITY_PROVIDER }} \ --source SOURCE_DIR \ --temporary-connection DBT_PROJECT_NAME run --target TARGET_NAME
のように、Snowflake との接続に関するオプションは DBT_PROJECT_NAME の前に置かなければいけません。
おわりに
今回は dbt project on Snowflake を運用するための開発環境とパイプラインのポイントについてご紹介しました。 開発環境の快適さは、開発スピードと品質に直結するので運用開始前にしっかり整備しておきたいですね。
Snowflake CLI は頻繁にアップデートされてどんどん便利になっていくので、バージョンごとの挙動の変化にも注意しながらよりよい環境を構築していきたい所存です 💪
