dbt

dbt の Environments 徹底ガイド:開発・ステージング・本番を安全に分離する

2026-04-19
NicheeLab編集部

dbt は「同じコードを別の環境に安全に適用する」ための仕組みを標準で備えています。コア(dbt Core)では profiles.yml の target と Jinja コンフィグで、dbt Cloud では Environment(Development / Deployment)と Job の組み合わせで実現します。

この記事では、安定的な本番運用と試験対策の両方で落とし穴になりやすい点(スキーマ分離、権限、deferral による Slim CI、テストの厳格度切替)を、具体例と運用パターンで解説します。

環境の基本概念:targets と Cloud Environments

dbt では「環境」を2層で扱います。ローカル/CLI では profiles.yml の outputs と target(例: dev/stg/prod)で接続先やスキーマを切り替えます。dbt Cloud では Environment(Development または Deployment)として資格情報・権限・対象プロジェクトを束ね、Job を特定 Environment に紐づけます。

重要なのは、物理的な分離(データベース/カタログ/スキーマ/データセット単位)を明確にすることです。これにより、開発者が誤って本番オブジェクトを上書きする事故を防げます。Snowflake なら別 Database/Schema、BigQuery なら別 Dataset、Databricks(Unity Catalog)なら Catalog/Schema での分離が基本方針です。

  • CLI: profiles.yml の target を切替(dbt run --target stg など)
  • Cloud: Environment ごとに Job を作成し、prod Job の実行権限を限定
  • 物理分離の優先度: Database/Project > Schema/Dataset > 単なる接頭辞のみ、の順で安全性が高い
環境目的物理配置(例)権限ポリシー
dev個人開発・実験SNOWFLAKE: DB=ANALYTICS, SCHEMA=DEV_<user>開発者にCREATE可、本番データはREADのみ
stg結合テスト・リハーサルBIGQUERY: project=analytics-stg, dataset=core_stg限定メンバーのみWRITE可
prod消費・配信DATABRICKS: catalog=prod, schema=martsCI/CDのみWRITE、閲覧者はREAD

環境分離の典型パターン(論理→物理)

DEV (target)schema: dev_<user> / write: developerSTG (target)dataset: core_stg / write: ci-botPROD (target)schema: marts / write: deployer onlyCloud Env: DevJob: none / adhocCloud Env: StagingJob: CI (slim)Cloud Env: ProductionJob: Scheduled Deploy環境分離の典型パターン(論理→物理)

dbt_project.yml: 環境名をスキーマに反映する(安全な衝突回避)

models:
  +materialized: table

# カスタム: スキーマ名に target.name を強制付与
macro-paths: ["macros"]

命名とスキーマ分離の設計:衝突しない規約を先に決める

最も事故が多いのは「同じスキーマに dev と prod が混在」する状態です。generate_schema_name マクロで target.name を必ず付与し、物理オブジェクトの衝突を防ぎます。個人開発は dev_<user> のように個人単位のスキーマを発行するのが安全です。

データウェアハウスごとの特性に合わせます。Snowflake は Database/Schema の2階層、BigQuery は Project/Dataset、Databricks(Unity Catalog)は Catalog/Schema/Volume など。prod はできるだけ上位階層から独立させるとロール管理が容易になります。

  • スキーマの自動命名: base_schema + _ + target.name (+ 任意の custom_schema)
  • 個人開発: dev_<user>、ステージング: <domain>_stg、本番: marts など役割ベース命名
  • リネームより再作成を優先(破壊的変更の影響を限定)
命名方針メリット/注意
schema = <base>_<target>core_dev / core_stg / core_prod単純で覚えやすい。prod でも接頭辞が付く点を許容できるか検討
user スキーマdev_alice, dev_bob並行開発に強い。権限管理とクリーンアップ運用が必要
階層分離優先Snowflake: DB=ANALYTICS_DEV/STG/PROD最も安全。コスト管理や権限制御が明瞭

macros/generate_schema_name.sql の例

{% macro generate_schema_name(custom_schema_name, node) -%}
  {%- set default_schema = target.schema -%}
  {%- if custom_schema_name is not none -%}
    {{ default_schema }}_{{ custom_schema_name }}_{{ target.name }}
  {%- else -%}
    {{ default_schema }}_{{ target.name }}
  {%- endif -%}
{%- endmacro %}

profiles.yml と targets:接続・スキーマ・資格情報を切り替える

dbt Core/CLI では profiles.yml の outputs に dev/stg/prod を定義し、target でどれを使うかを切り替えます。各 output に接続先、スキーマ/データセット、ロール/権限を明示します。環境変数は env_var で読み込みます。

Snowflake/BigQuery/Databricks いずれでも、prod は書き込み主体を CI/CD(サービスアカウント)に限定し、開発者は読み取り中心にします。これにより、誤更新や秘密情報の露出を防げます。

  • dbt run --target stg でステージングに明示デプロイ
  • 本番 only のロール・キーファイルをサービスアカウント化
  • スキーマは profiles.yml の schema と generate_schema_name の両輪で制御

profiles.yml(例:Snowflake)

my_project:
  target: dev
  outputs:
    dev:
      type: snowflake
      account: {{ env_var('SF_ACCOUNT') }}
      user: {{ env_var('SF_USER') }}
      password: {{ env_var('SF_PASSWORD') }}
      role: DEV_ROLE
      database: ANALYTICS
      warehouse: DEV_WH
      schema: core
    stg:
      type: snowflake
      account: {{ env_var('SF_ACCOUNT') }}
      user: {{ env_var('CI_USER') }}
      password: {{ env_var('CI_PASSWORD') }}
      role: STG_ROLE
      database: ANALYTICS_STG
      warehouse: CI_WH
      schema: core
    prod:
      type: snowflake
      account: {{ env_var('SF_ACCOUNT') }}
      user: {{ env_var('DEPLOY_USER') }}
      password: {{ env_var('DEPLOY_PASSWORD') }}
      role: PROD_ROLE
      database: ANALYTICS_PROD
      warehouse: PROD_WH
      schema: marts

dbt Cloud の Environment と Job:本番を守る運用設計

dbt Cloud では、Environment に接続情報・ロール・デプロイ可否をまとめ、Job は必ず特定の Environment に紐づきます。Development Environment は開発者が IDE で使い、Deployment Environment は CI/CD やスケジュール実行で使用します。

本番 Job は承認フローや限定ロールで保護し、ステージング Job は PR 単位で実行(CI)してから本番 Job を走らせる二段構成にします。UI のラベルは時期により変わる可能性がありますが、Environment と Job の紐付け・分離という設計原則は安定しています。

  • 各 Job は必ず prod/stg など専用 Environment にバインド
  • prod Job 実行権限を最小化(Bot/Service に限定)
  • Artifacts の保持期間を十分に確保(deferral で使用)

Job コマンド例(Cloud/CLI 共通イディオム)

dbt build --target prod --select tag:marts+

CI とステージング:deferral + state で Slim CI を実現

PR で全リビルドをすると高コストです。deferral と state を組み合わせる Slim CI では、過去の本番(またはステージング)成果物を参照しつつ、変更影響範囲だけを再ビルドします。これにより、速く安定した検証が可能になります。

dbt Cloud の Job では『Defer to a previous run state』相当の設定があり、参照元として prod の最新アーティファクトを指定します。CLI では --defer と --state オプションを使います。

  • state:modified+ セレクタで変更とその依存先を選択
  • --defer で未変更ノードは参照のみ(再ビルドしない)
  • CI 成果は stg 環境にのみ書き込み、prod は参照先としてのみ使用

Slim CI(PR)での典型コマンド

dbt build \
  --target stg \
  --select state:modified+ \
  --defer \
  --state path/to/prod_artifacts

権限・テスト・リリース安全策:本番事故を未然に防ぐ

環境に応じてテストの厳格度や GRANTS を切り替えます。prod では致命的テストで失敗させ、dev では警告や無効化でスピードを優先します。dbt の tests は Jinja で enabled/severity を環境条件にできます。モデルの grants も target.name で条件分岐可能です。

破壊的変更(カラム削除など)はステージングでデータ検証を済ませ、prod では段階的リリースかリネーム+移行で安全に進めます。スケジュール Job は前段のステージング成功をトリガーにし、ロールバックはアーティファクトの固定バージョンを参照します。

  • tests の enabled/severity を target.name で条件化
  • models の grants を prod のみ付与
  • 破壊的変更はステージングでのデータプロファイル・可視化を必須化

環境別の tests/grants 設定例

# tests(schema.yml)
version: 2
models:
  - name: fct_orders
    columns:
      - name: order_id
        tests:
          - not_null:
              name: not_null_order_id
              enabled: "{{ target.name != 'dev' }}"
              severity: "{{ 'error' if target.name == 'prod' else 'warn' }}"

# grants(dbt_project.yml または models/*.yml のモデル設定)
models:
  marts:
    +grants:
      select: "{{ ['ANALYST_ROLE'] if target.name == 'prod' else [] }}"

問題で確認

Analytics Engineer

問題 1

PR の CI で、過去の本番成果物を参照しつつ変更影響範囲だけを再ビルドしたい。最も適切なコマンドはどれか。

  1. A. dbt build --target stg --select state:modified+ --defer --state path/to/prod_artifacts
  2. B. dbt run --target prod --select +tag:ci --full-refresh
  3. C. dbt build --target stg --select tag:ci --full-refresh
  4. D. dbt test --target stg --defer --state path/to/prod_artifacts

正解: A

Slim CI の定石は state:modified+ で変更と依存を選択し、--defer と --state で本番アーティファクトを参照して未変更ノードの再ビルドを避ける。B は本番に直接書き込み、C は全更新でコスト過大、D はビルドを伴わないため不十分。

よくある質問

dbt Cloud の Environment と profiles.yml の target は何が違いますか?

profiles.yml の target は CLI/ローカルでの接続先やスキーマ切替を表し、dbt Cloud の Environment はクラウド側での資格情報・ロール・ランタイムを束ね、Job と厳密に紐づく運用単位です。原理は同じでも適用層が異なります。

ステージングを省略して dev→prod に直接デプロイしても良いですか?

推奨しません。ステージングはスキーマ変更や依存関係の検証、データ品質テストのリハーサルに不可欠です。特に破壊的変更や増分モデルでは、stg での Slim CI による差分検証が本番事故の主要な防波堤になります。

prod と stg を同じ Database/Project 内の別スキーマで運用しても安全ですか?

最小要件は満たせますが、本番の権限・コスト・データ保持をより強固に分離するには上位階層(Snowflake の別 Database、BigQuery の別 Project、Databricks の別 Catalog)を分ける方が安全です。可能なら階層も分離してください。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
dbt

dbt Model の基礎: SQL で定義する変換の最小単位

Analytics Engineer 向けに、dbt Model の定義、マテリアライゼーション、依存関係、インクリメン...

dbt

dbt Analytics Engineer 試験ガイド: 出題範囲・配点・申込の実務視点

dbt Analytics Engineer 認定の出題範囲、配点の考え方、申込から受験までの流れを、公式ドキュメントの...

dbt

dbt Cloud と dbt Core の違いと選び方:Analytics Engineer 試験に効く要点

dbt Cloud と dbt Core の機能差を、実務と資格対策の両面から整理。スケジューリング、IDE、RBAC、...

dbt

dbt プロジェクト構造ガイド: models / seeds / macros の実務レイアウト

Analytics Engineer 向けに、dbt プロジェクトのディレクトリ構造と命名規約、dbt_project....

dbt

dbt_project.yml の読み方:主要設定と命名を最短で掴む

dbt_project.yml の必須キー、命名解決(database.schema.identifier)、設定優先度...

dbtの記事一覧 (100件)
© 2026 NicheeLab All rights reserved.