データベース

dbtとSnowflakeの連携:キーペア認証の接続設定とdbt Projects on Snowflakeの使い分け【2026年版】

dbtとSnowflakeの連携:キーペア認証の接続設定とdbt Projects on Snowflakeの使い分け【2026年版】

dbtとSnowflakeの連携は、2026年に前提が2つ変わりました。サービス用ユーザーのパスワード認証が順次止まり、dbtの実行そのものをSnowflakeの中で済ませる「dbt Projects on Snowflake」が選べるようになったことです。この記事では、2026年11月時点の公式ドキュメントとPyPIの実測をもとに、dbt専用のロールとサービスユーザーの作成、キーペア認証のprofiles.yml、Snowflake固有のモデル設定、CREATE DBT PROJECTとタスクによる定期実行までを、コピーして動かせる形で整理しました。最後に、外部でdbtを動かす構成とSnowflake内で動かす構成のどちらを選ぶかも言い切ります。

まとめ:dbtとSnowflakeの連携は鍵認証と実行場所の選択で決まる

外部のサーバーやCIからdbtを動かすなら、TYPE = SERVICEのユーザーにキーペア認証を設定し、profiles.ymlで秘密鍵のパスとパスフレーズを環境変数から渡します。パスワードで接続している既存の設定は、そのままでは動かなくなります。

Snowflakeだけを相手にし、日次や時間単位のバッチで足りるなら、dbt Projects on Snowflakeを選びます。追加ライセンスは不要で、費用はウェアハウスの稼働分だけです。実行サーバーと認証情報の管理が丸ごと要らなくなります。

複数のDWHを扱う、dbt platform(旧dbt Cloud)を使っている、取り込みやBIを含む外部のワークフローから順番に呼びたい、のいずれかに当てはまる場合は外部実行を残してください。

dbtとSnowflakeの連携構成:外部実行とSnowflake内実行の違い

連携の方法は、dbtをどこで動かすかで2つに分かれます。

dbt-snowflake 1.12系の外部実行とSnowflake内ランタイム

1つ目は、手元のPCやCI、コンテナにdbtとdbt-snowflakeアダプタを入れ、ネットワーク越しにSnowflakeへSQLを送る従来の構成です。2026年11月11日時点のPyPIでは、dbt-snowflakeの最新は1.12.5(11月4日公開)で、対応Pythonの分類子は3.10〜3.13です。

2つ目がdbt Projects on Snowflakeです。dbtのプロジェクトをスキーマ配下の「DBT PROJECTオブジェクト」としてデプロイし、Snowflakeが用意したdbtのランタイムで実行します。公式ドキュメントは、追加のSnowflakeライセンスもユーザー単位の料金も無く、実行時のウェアハウス代だけがかかると明記しています。

認証・スケジュール・dbtの版・パッケージ取得で比べる2構成の差

同じdbtのプロジェクトでも、運用の手間が生じる場所は構成ごとに違います。

比較項目 外部実行(dbt-snowflake) Snowflake内(dbt Projects)
認証の管理 サービスユーザーと秘密鍵を自前で管理 実行ユーザーとロールで動くため鍵は不要
実行サーバー CIやコンテナ基盤を用意する 不要(ウェアハウスで実行)
スケジュール cron・Airflow・dbt platform Snowflakeのタスク・Airflow
dbtの版 pipで任意の版を固定 Snowflakeが提供する版から選ぶ
パッケージ取得 実行環境の通信で取得 外部アクセス統合か事前取得が要る
接続先 BigQuery等と同じ書き方で共存できる Snowflakeだけ

実務で差が大きいのは、上の2行です。鍵の配布とローテーション、実行サーバーの保守が消えるかどうかで、運用の人手が変わります。dbtそのものの仕組みやCore・platformの違いは、dbtとは?ELTのTを担う仕組みとdbt Core・Cloudの選び方で整理しています。

Snowflake側の準備:dbt専用のロール・ウェアハウス・サービスユーザー

どちらの構成でも、dbtが使うロールとウェアハウスは先に分けておきます。

2026年8〜10月に止まったサービスユーザーのパスワード認証と移行先

Snowflakeは単一要素のパスワードによるサインインを3段階で廃止しています。廃止計画のドキュメントによると、第3段階は2026年8〜10月にアカウントごとに順次適用され、人間のユーザーはパスワード単独では認証できない仕様です。サービスユーザーのパスワード認証も全面的に禁止され、移行用に残されていたLEGACY_SERVICEのユーザーはSERVICEへ切り替えられます。

日付は見積もりで、移行に時間がかかるアカウントでは延びる場合があります。それでも、dbtの接続をパスワードのまま残す理由はもうありません。dbtの接続ドキュメントも、個人の開発者にはパスワードではなくMFAかSSOを使うよう案内しています。人が介在しない自動実行は、次の手順のキーペア認証に切り替えます。

TRANSFORMERロールとXSMALLウェアハウスを用意するGRANT文の実行例

dbtに与える権限は、生データの読み取りと、変換結果を置くデータベースへの書き込みの2系統です。ACCOUNTADMINではなく、専用ロールで動かします。

-- dbt専用のウェアハウスとロール
CREATE WAREHOUSE IF NOT EXISTS transforming
  WAREHOUSE_SIZE = XSMALL
  AUTO_SUSPEND = 60
  AUTO_RESUME = TRUE;
CREATE ROLE IF NOT EXISTS transformer;
GRANT USAGE ON WAREHOUSE transforming TO ROLE transformer;

-- 生データ(raw)は読み取りだけ
GRANT USAGE ON DATABASE raw TO ROLE transformer;
GRANT USAGE ON ALL SCHEMAS IN DATABASE raw TO ROLE transformer;
GRANT SELECT ON ALL TABLES IN DATABASE raw TO ROLE transformer;
GRANT SELECT ON FUTURE TABLES IN DATABASE raw TO ROLE transformer;

-- 変換結果(analytics)はスキーマ作成まで許可
GRANT USAGE, CREATE SCHEMA ON DATABASE analytics TO ROLE transformer;

FUTURE TABLESの付与を忘れると、取り込みツールが新しく作ったテーブルを読めずにdbt buildが失敗します。取り込みをFivetranなどに任せる構成は、Fivetranとは?ELTの仕組み・MAR課金・dbt統合後の構成で分担を説明しました。

opensslでPKCS#8鍵を作りサービスユーザーに公開鍵を登録する手順

外部実行の認証は、キーペア認証で組みます。dbtの接続ドキュメントは、v2ではPKCS#8形式をAES-256で暗号化した鍵を推奨し、旧来の3DES暗号やヘッダの無い鍵には対応しないと書いています。

# 秘密鍵(AES-256で暗号化したPKCS#8)と公開鍵を作る
openssl genrsa 2048 | openssl pkcs8 -topk8 -v2 aes-256-cbc -inform PEM -out rsa_key.p8
openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub

-- Snowflake側:人が使わないSERVICE型のユーザーに公開鍵を登録する
CREATE USER IF NOT EXISTS dbt_svc
  TYPE = SERVICE
  DEFAULT_ROLE = transformer
  DEFAULT_WAREHOUSE = transforming
  RSA_PUBLIC_KEY = 'MIIBIjANBgkqh...(rsa_key.pubの本文。先頭行と末尾行は除く)';
GRANT ROLE transformer TO USER dbt_svc;

鍵を入れ替えるときは、2本目の枠であるRSA_PUBLIC_KEY_2に新しい公開鍵を登録し、dbt側を切り替えてから古い方を外します。止めずにローテーションできるので、期限を決めて回す運用に向きます。

dbt-snowflakeのインストールとキーペア認証のprofiles.yml設定

ここからは外部実行の構成です。Snowflake内実行だけを使う場合は、次の章へ進んでください。

Python 3.12のvenvでdbt本体とアダプタの版を指定する手順

dbt-core 1.8以降、アダプタはdbt本体を依存として引き込みません。本体とアダプタは、どちらも1.12系に版を固定して並べて入れます。

python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install "dbt-core~=1.12.0" "dbt-snowflake~=1.12.0"
dbt --version

pip install dbtとだけ打つと、2026年9月以降はRust製のdbt v2が入ります。v2を選ぶかどうかの判断材料はdbt Fusionとは:dbt v2になったRust製エンジンとCoreの違いにまとめました。dbt Core一般のインストールとprofiles.ymlの探索順はdbt Coreの使い方:インストールからprofiles.yml・dbt build・CIまでの手順で扱っています。

profiles.ymlの秘密鍵設定:private_key_pathと環境変数

dbt-snowflakeのソース(SnowflakeCredentials)が受け付ける項目のうち、キーペア認証で使うのはprivate_key_pathとprivate_key_passphraseです。鍵の中身を直接渡すprivate_keyもあります。

# ~/.dbt/profiles.yml
shop:
  target: dev
  outputs:
    dev:
      type: snowflake
      account: "{{ env_var('SNOWFLAKE_ACCOUNT') }}"   # 例: myorg-myaccount
      user: dbt_svc
      role: transformer
      private_key_path: "{{ env_var('SNOWFLAKE_PRIVATE_KEY_PATH') }}"
      private_key_passphrase: "{{ env_var('DBT_ENV_SECRET_SNOWFLAKE_KEY_PASSPHRASE') }}"
      warehouse: transforming
      database: analytics
      schema: dbt_dev
      threads: 8
      query_tag: dbt_dev
      reuse_connections: true
      connect_retries: 3

accountには、組織名とアカウント名をハイフンでつないだ識別子を入れます。パスフレーズの環境変数名をDBT_ENV_SECRET_で始めると、ログに値が出ても伏せ字になります。connect_retriesの既定は1回なので、CIの瞬断で落ちるのが気になる場合は上の例のように増やしてください。

dbt debugの疎通確認とPKCS#1エラーなど接続失敗の切り分け方

設定を書いたらdbt debugを実行し、profiles.ymlの読み込みと接続の両方が通ることを確かめます。失敗したときは、表示されるメッセージで原因の場所が分かります。

  • 「Key is PKCS#1 (RSA private key). Snowflake requires PKCS#8」:openssl genrsaの出力をそのまま使っています。前の章のコマンドで鍵を作り直します。
  • JWTトークンが無効という趣旨のエラー:Snowflakeに登録した公開鍵と、手元の秘密鍵が対になっていません。DESC USER dbt_svcで登録済みの鍵の指紋を確認します。
  • ウェアハウスやデータベースが存在しない旨のエラー:多くは権限不足です。ロールにUSAGEが付いていないと、オブジェクトは「無い」と表示されます。

3つ目は見落としやすく、名前の綴りを何度も見直して時間を失う典型です。roleを明示して、同じロールでSnowsightから同じオブジェクトが見えるかを先に確かめると早く片づきます。

Snowflakeモデルのtransient・query_tag・実行先設定

接続できたら、Snowflakeだけに効く設定をプロジェクトに入れておきます。

既定でtransientになるテーブルと本番で永続テーブルに戻す場面

Snowflake configurationsによると、dbtが作るSnowflakeのテーブルは既定でtransientです。transientテーブルにはフェイルセーフ期間が無く、そのぶんストレージ費用が下がります。dbt buildで毎回作り直せるモデルなら、既定のままで困りません。

一方、増分モデルのように作り直しに何時間もかかる表や、誤削除からの復旧手段を残したい表は、+transient: falseで永続テーブルにします。全モデル一律ではなく、増分モデルのフォルダだけに指定するのが無駄の少ない分け方です。

query_tagとsnowflake_warehouseでモデル単位に費用を追う設定例

Snowflakeの費用はウェアハウスの稼働時間で決まります。重いモデルだけ大きいウェアハウスに逃がし、どのモデルが何を使ったかをタグで追えるようにします。

# dbt_project.yml
models:
  shop:
    +query_tag: dbt_shop
    +snowflake_warehouse: transforming
    marts:
      +transient: false
    events:
      +snowflake_warehouse: transforming_l
      +query_tag: dbt_shop_events

付けたタグはQUERY_HISTORYのQUERY_TAG列に残るので、タグごとの実行時間を集計すれば重いモデル群が見えてきます。スキャン量で課金するBigQueryとの費用構造の違いは、BigQueryとSnowflakeの比較:課金モデルの構造差と同時実行で決める選定基準で比べました。

増分モデルのmerge既定とdynamic_tableの更新間隔設定例

増分モデルのincremental_strategyは、既定がmergeで、ほかにappend、delete+insert、insert_overwrite、microbatchを選べます。数分おきの鮮度が欲しい集計なら、Snowflakeのdynamic tableとして作る手もあります。

-- models/marts/fct_sessions.sql
{{ config(
    materialized='dynamic_table',
    snowflake_warehouse='transforming',
    target_lag='15 minutes',
    refresh_mode='AUTO'
) }}
select session_id, user_id, min(event_at) as session_start
from {{ ref('stg_events') }}
group by session_id, user_id

dynamic tableではsnowflake_warehouseが必須です。target_lagを書くとdbtがスケジューラを有効にし、以降はdbtを動かさなくてもSnowflakeが更新を続けます。また、on_schema_change='sync_all_columns'の増分モデルに照合順序付きの文字列列がある場合、dbt-snowflake 1.10.6未満ではSnowflake側の列サイズ変更でビルドが失敗し得ると公式が注意しています。1.12系に上げておけば該当しません。レイヤの分け方そのものはdbtのmarts層とは?3層の分け方とMetricFlowで指標を定義する手順を参照してください。

dbt Projects on Snowflakeでデプロイしタスクで定期実行する手順

ここからはSnowflake内実行の構成です。開発はSnowsightのWorkspacesで行い、本番はGitリポジトリからデプロイします。

profiles.ymlのaccountとuserが空でよい理由と使えるdbtの版

制限事項のページによると、プロジェクトは実行したアカウントとユーザーの文脈で動くため、accountとuserは空文字列で構いません。ターゲットに書くのはウェアハウス、データベース、スキーマ、ロールです。

# profiles.yml(dbt Projects on Snowflake用)
shop:
  target: prod
  outputs:
    prod:
      type: snowflake
      account: ''
      user: ''
      role: transformer
      warehouse: transforming
      database: analytics
      schema: dbt_prod
      threads: 8

使える版は対応バージョンの一覧にあり、2026年11月時点でdbt Core 1.9.4・1.10.15・1.11.11・1.12.3と、dbt Fusionの2.0.0系です。SELECT SYSTEM$SUPPORTED_DBT_VERSIONS();で手元のアカウントの値を確かめられます。版を指定しないと実行時の既定が1.9.4になるため、作成時にDBT_VERSIONを明示してください。

Gitから本番を動かすSQL:DBT PROJECTの作成と実行の手順

Gitとの接続(API統合とGitリポジトリオブジェクト)は、Snowsightとは:Workspaces移行後の使い方・Git連携の手順で作れます。そのリポジトリのブランチを指定して、CREATE DBT PROJECTでオブジェクトにします。

-- mainブランチからdbtプロジェクトを作る(版は明示する)
CREATE DBT PROJECT IF NOT EXISTS analytics.dbt.shop_project
  FROM '@analytics.dbt.shop_repo/branches/main'
  DBT_VERSION = '1.12.3'
  DEFAULT_TARGET = 'prod'
  EXTERNAL_ACCESS_INTEGRATIONS = (dbt_ext_access)
  COMMENT = 'shop の変換モデル';

-- 手動で実行する(ARGSを省くと dbt run)
EXECUTE DBT PROJECT analytics.dbt.shop_project
  ARGS = 'build --target prod';

EXECUTE DBT PROJECTには、DBT_VERSIONで版を一時的に上書きする指定や、同時実行用のWRITEBACK = FALSEもあります。ファイルを更新するたびにCREATE OR REPLACEで作り直すと、実行履歴が消えることがあります。更新にはALTER DBT PROJECTのデプロイを使ってください。CIから回す場合は、Snowflake CLI(11月9日公開の3.33.0、Python 3.11以上)のsnow dbt deployとsnow dbt executeが同じ操作に当たります。

dbt depsの外部アクセス統合とhub.getdbt.comの通信許可

dbt_utilsのようなパッケージを使うなら、Snowflakeから外へ取りに行く通信の許可が要ります。依存関係のページが挙げる宛先は2つです。

CREATE OR REPLACE NETWORK RULE analytics.dbt.dbt_network_rule
  MODE = EGRESS
  TYPE = HOST_PORT
  VALUE_LIST = ('hub.getdbt.com', 'codeload.github.com');

CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION dbt_ext_access
  ALLOWED_NETWORK_RULES = (analytics.dbt.dbt_network_rule)
  ENABLED = TRUE;

GRANT USAGE ON INTEGRATION dbt_ext_access TO ROLE transformer;

統合をプロジェクトに付けておくと、デプロイ時にdbt depsとdbt compileが自動で走ります。外部への通信を開けられない社内規程なら、CIでdbt depsを済ませ、dbt_packagesごとデプロイする方法を取ります。デプロイできるのは生成物を含めて10万ファイルまでです。

CREATE TASKで毎朝dbt buildを回す設定とサーバーレス非対応の制約

定期実行はSnowflakeのタスクに任せます。制限事項のページによると、サーバーレスタスクからdbtプロジェクトは実行できないため、WAREHOUSEを必ず指定します。

CREATE OR REPLACE TASK analytics.dbt.shop_daily_build
  WAREHOUSE = transforming
  SCHEDULE = 'USING CRON 0 6 * * * Asia/Tokyo'
AS
  EXECUTE DBT PROJECT analytics.dbt.shop_project
    ARGS = 'build --target prod';

ALTER TASK analytics.dbt.shop_daily_build RESUME;

作成直後のタスクは停止状態なので、最後のRESUMEを忘れると一度も動きません。実行の成否とdbt buildの出力は、Snowsightの実行履歴とクエリの詳細から追えます。ログとトレースを細かく見たい場合は、オブジェクトにLOG_LEVELとTRACE_LEVELを設定しておきます。

構成の選び方:dbt Projects on Snowflakeを採用する条件と見送る場面

ここまでの仕様を踏まえ、どちらを選ぶかを条件で決めます。

Snowflake単一基盤の日次バッチならSnowflake内実行を選ぶ条件

次の3つがそろうなら、dbt Projects on Snowflakeを選びます。変換の対象がSnowflakeだけであること。更新が日次か時間単位のバッチで足り、前後の処理をSnowflakeのタスクでつなげること。dbtの版をSnowflakeの提供版(2026年11月時点で1.12.3まで)に合わせられることです。

この条件なら、実行サーバー、秘密鍵の配布、dbt platformのシート費用がまとめて不要になります。データ担当者が1〜2人の組織ほど、保守から解放される効果は大きく出ます。

外部実行を残すべき3つの場面とSnowflake内へ移して失敗する例

外部実行を残すのは、次のいずれかに当てはまる場合です。BigQueryやPostgreSQLなど別のDWHも同じチームで変換している。dbt platformのIDEやジョブ、Semantic Layerをすでに使っている(dbt Cloudのプロジェクトはそのまま移せません)。取り込みツールの完了を待ってからdbtを動かし、BIの更新まで1本のワークフローで管理している。

失敗の典型は、Workspacesで開発したプロジェクトを、パッケージ取得の通信を許可しないまま本番のタスクに載せる例です。手元では動いたのにデプロイでdbt depsが失敗し、朝の集計が止まります。もう1つは、版を指定せずに作成し、既定の1.9.4で動いて新しい構文が通らないケースです。どちらも、本番用の作成SQLにEXTERNAL_ACCESS_INTEGRATIONSとDBT_VERSIONを必ず書くという決まりで防げます。

dbtとSnowflakeの基盤設計を外部へ相談する目安と依頼範囲

接続とモデル設定は、この記事の手順で社内でも組めます。外部の手を借りる価値があるのは、ロールとウェアハウスの割り当て、取り込みから変換・BIまでの実行順、外部実行とSnowflake内実行のどちらに寄せるかを一度に決める局面です。パスワード認証の停止で既存のdbtジョブが止まり、作り直しを機に構成を見直す場合も同じです。一創ではデータ分析基盤構築・MLOps構築支援として、Snowflakeとdbtを含むデータ基盤の設計・構築から運用ルールづくりまでを請け負っています。

よくある質問

dbtとSnowflakeの連携で挙がりやすい質問に答えます。

dbt Projects on Snowflakeの料金はいくらかかりますか?

機能そのものの料金はありません。公式ドキュメントは、追加のSnowflakeライセンスもユーザー単位の料金も不要で、実行に使った仮想ウェアハウスの通常のコンピュート費用がかかると説明しています。XSMALLのウェアハウスで毎朝1回dbt buildを回すなら、費用はその稼働時間ぶんのクレジットです。タスクから回す場合も、指定したウェアハウスの稼働分が加わるだけです。

Snowflakeのパスワード認証のままdbtを使い続けられますか?

使い続けられないと考えてください。単一要素のパスワード認証は、2026年8〜10月の第3段階で人間のユーザーにもサービスユーザーにも使えなくなります。適用日はアカウントごとに異なりますが、自動実行はキーペア認証へ、個人の開発はMFAかSSO(authenticator: externalbrowser)へ切り替えてください。SSOは接続のたびにブラウザでの認証が入ります。

dbt CloudとSnowflakeを連携する手順は違いますか?

dbt Cloud(現在の名称はdbt platform)では、profiles.ymlを書く代わりに画面で接続を設定します。アカウント識別子、ロール、ウェアハウス、データベースを入れる点と、キーペアかOAuthで認証する点は同じです。Snowflake側のロールとサービスユーザーの準備は、この記事のSQLをそのまま使えます。なお、dbt Cloudのプロジェクトをdbt Projects on Snowflakeへそのまま載せることはできません。

dbt Projects on Snowflakeでdbt Fusion(v2)は使えますか?

使えます。対応バージョンの一覧には、dbt Core 1.x系と並んでdbt Fusionの2.0.0とプレビュー版が載っています。DBT_VERSIONに1.xを指定するとPython製のdbt Core、2.xを指定するとRust製のFusionで動く仕組みです。既存プロジェクトをFusionで動かす前に、非推奨警告の解消など移行の準備を済ませておきます。

Snowflakeの開発環境と本番環境はどう分ければよいですか?

profiles.ymlのtargetで、スキーマを分けるのが基本です。開発はdbt_dev、本番はdbt_prodのように書き分け、実行時に--target prodで切り替えます。さらに安全にするなら、本番用のロールだけが本番スキーマへ書き込めるよう権限を分けます。ウェアハウスも開発用と本番用で分けておくと、開発中の重いクエリが朝の本番実行を待たせません。

関連記事

お気に入りに入れた記事の一覧

一創の公式 SNS

X では毎朝の新着記事と IT ニュースの速報を、YouTube・TikTok・Instagram・LinkedIn・Facebook では記事の解説動画を配信しています。

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.11.09 テックブログ エディオン不正アクセス第2報:カード番号の対象確認とログ・決済画面の改ざん対策
  2. 2026.11.10 テックブログ ニトリの情報漏洩:最大3,762万件の対象確認となりすまし連絡の見分け方
  3. 2026.11.10 テックブログ Claude Fable 5.2とは:料金・破壊的変更4点とFable 5.1からの移行手順【2026年11月】
  4. 2026.11.09 テックブログ LANSCOPE不正アクセス第2報:製品への影響と偽連絡の確認、停止中のライセンス認証の窓口
  5. 2025.04.30 テックブログ IMSIキャッチャー(偽基地局)とは?2Gフォールバックの手口と日本での対策

RELATED POSTS 関連記事

目次