dbt Projects on Snowflake 오케스트레이션 이해하기

dbt Projects on Snowflake 오케스트레이션 이해하기

오케스트레이션은 배포된 dbt 프로젝트 객체 실행을 스케줄링·시퀀싱·모니터링하는 프로세스예요. dbt Projects on Snowflake의 모든 오케스트레이션 접근 방식은 같은 기본 메커니즘(EXECUTE DBT PROJECT SQL 명령)을 사용해요. Snowflake 태스크를 쓰든 Apache Airflow 같은 외부 도구를 쓰든, 오케스트레이터의 역할은 그 명령을 올바른 시간에, 올바른 순서로, 올바른 매개 변수로 호출하는 것이에요.

두 가지 경로가 있어요:

  • Snowflake 태스크: 외부 인프라가 없는 네이티브 스케줄링. 운영 오버헤드를 줄이고 Snowflake에 표준화하려는 팀에 가장 적합해요.
  • 외부 오케스트레이터(Apache Airflow, Prefect, Dagster): 기존 오케스트레이션 인프라가 있거나 Snowflake를 넘어서는 교차 시스템 워크플로가 있는 팀용.

여러 스케줄이나 워크플로 분기가 같은 시간에 같은 dbt 프로젝트 객체를 실행해야 한다면 Snowflake는 WRITEBACK=FALSE를 권장해요. Snowflake는 이 설정과 관계없이 쿼리별 결과 아티팩트와 아카이브를 저장해요. 검색 방법은 프로그래밍 방식으로 dbt 아티팩트와 로그 접근 문서를 참조하세요.

writeback이 필요하다면 서로 겹치지 않는 별도의 target과 log 디렉터리를 사용하세요. 예시는 dbt 프로젝트 객체를 동시에 실행 문서를 참조하세요.

출처: Snowflake 문서

본문

오케스트레이션 접근 방식 선택

고려 사항 Snowflake 태스크 Apache Airflow
인프라 없음. Snowflake가 완전 관리. 자체 관리 Airflow 클러스터 또는 관리형 서비스.
모니터링 내장 Snowsight 실행 기록, 이벤트 테이블, 쿼리별 dbt 아티팩트 접근. Airflow UI와 커스텀 통합.
스케줄링 CRON 식, 고정 간격, AFTER(태스크 체이닝), 또는 스트림에 새 데이터가 있을 때 트리거. DAG 수준 구성을 가진 Airflow 스케줄러.
다단계 파이프라인 AFTER 절이 태스크를 그래프로 연결. 트리거 규칙이 있는 DAG 의존성(예: 모두 성공, 또는 하나 실패).
동적 매개 변수 EXECUTE DBT PROJECT의 ENV_VARS, EXECUTE DBT PROJECT의 ARGS 문자열의 --vars, 또는 태스크 CONFIG의 동적 실행별 값. 런타임에 동적 구성 전달 문서 참조. SQL 또는 CLI 명령에 보간되는 Airflow Jinja 템플릿.
비용 태스크 실행에 대한 웨어하우스 크레딧만. Airflow 인프라 비용 + 웨어하우스 크레딧.
가장 적합한 대상 Snowflake 네이티브, 새로 시작, 또는 도구를 통합하는 팀. 기존 Airflow DAG가 있거나 교차 시스템 워크플로가 있는 팀.

dbt 프로젝트 객체 수준의 내장 모니터링

dbt 프로젝트 객체가 어떻게 실행되든 같은 관측성과 관리 기능을 얻어요. 이 기능들은 오케스트레이터가 아니라 배포된 dbt 프로젝트 객체 자체에 연결돼 있어요:

  • Snowsight의 실행 기록: 탐색 메뉴에서 Transformation > dbt Projects를 선택해 dbt 프로젝트 객체의 모든 실행(태스크, Airflow, 또는 임시 SQL 호출로 트리거됐든)에 대한 실행 기록, 태스크 그래프, 쿼리 세부 정보를 봐요.
  • 컬럼 수준 혈통이 있는 프로젝트 DAG: 프로젝트 세부 정보 페이지에서 모델 의존성 그래프를 탐색하고, 컴파일된 SQL을 검사하고, Snowflake Horizon Catalog 기반 컬럼 수준 혈통을 추적해요.
  • 이벤트 테이블 로깅과 추적: Snowflake가 각 실행에 대한 로그 항목과 추적 span을 계정의 활성 이벤트 테이블에 기록해요. 실행 중 또는 완료 후에 이벤트 테이블을 라이브로 쿼리해 실패를 진단해요.
  • dbt 아티팩트에 대한 프로그래밍 방식 접근: 알려진 실행 쿼리 ID로 SYSTEM$LOCATE_DBT_ARTIFACTS를 사용해 manifest.json, run_results.json, 로그 파일을 프로그래밍 방식으로 검색해요.
  • Cortex Code 통합: Cortex Code를 사용해 배포된 dbt 프로젝트 객체의 파일을 검사하고, 프로덕션 실패를 디버깅하고, 파이프라인에 대한 질문에 답해요.

이 기능들을 활성화·사용하는 방법은 dbt 프로젝트 모니터링 및 기존 dbt 프로젝트 정보 보기·관리 문서를 참조하세요.

Snowflake 태스크로 오케스트레이션

Snowflake 태스크는 dbt 프로젝트 객체 실행에 네이티브 스케줄링을 제공해요. 외부 인프라를 프로비저닝하거나 관리할 필요가 없어요. 태스크를 만들고 스케줄을 설정하면 Snowflake가 나머지를 처리해요.

이점

  • 프로비저닝하거나 관리할 인프라가 없음.
  • 실행 기록, 태스크 그래프, 쿼리 수준 실행 세부 정보를 가진 Snowsight의 내장 모니터링.
  • RBAC 거버넌스 스케줄링: 태스크를 만들고 소유하고 다시 시작할 수 있는 사람을 제어.
  • 태스크 그래프를 통한 내장 재시도 로직과 알림.

태스크는 저장 프로시저를 통해 외부 호출(예: 다운스트림 API 트리거)도 할 수 있지만, 이를 위해서는 외부 접근 통합과 네트워크 정책 구성이 필요해요.

Snowsight에서 스케줄

Snowsight의 두 곳(Workspaces 또는 dbt 프로젝트 객체의 객체 세부 정보 페이지)에서 배포된 dbt 프로젝트 객체를 스케줄로 실행하는 태스크를 만들고 보고 관리할 수 있어요. 지침은 Snowflake에서 dbt 프로젝트 객체 실행 스케줄링 문서를 참조하세요.

간단한 예약 태스크 만들기

다음 예시는 6시간마다 배포된 dbt 프로젝트 객체를 실행하는 태스크를 만들어요:

CREATE OR ALTER TASK my_db.my_schema.run_dbt_every_6h
  WAREHOUSE = transform_wh
  SCHEDULE = '360 minutes'
AS
  EXECUTE DBT PROJECT my_db.my_schema.my_project ARGS='run --target prod';

태스크를 다시 시작해 활성화해요:

ALTER TASK my_db.my_schema.run_dbt_every_6h RESUME;

여러 단계가 있는 태스크 그래프 만들기

AFTER 절을 사용해 태스크를 태스크 그래프로 연결해요. 다음 예시는 먼저 모델을 실행하고 모델이 완료된 후 테스트를 실행하는 2단계 파이프라인을 만들어요:

-- DAG 순서로 모든 모델 실행
CREATE OR ALTER TASK my_db.my_schema.run_dbt_models
  WAREHOUSE = transform_wh
  SCHEDULE = '360 minutes'
  AS
    EXECUTE DBT PROJECT my_db.my_schema.my_project ARGS='run --target prod';

-- 모델이 성공적으로 완료된 후 테스트 실행
CREATE OR ALTER TASK my_db.my_schema.run_dbt_tests
  WAREHOUSE = transform_wh
  AFTER my_db.my_schema.run_dbt_models
  AS
    EXECUTE DBT PROJECT my_db.my_schema.my_project ARGS='test --target prod';

-- 그래프를 활성화하려면 루트 태스크 다시 시작
ALTER TASK my_db.my_schema.run_dbt_models RESUME;

루트 태스크가 발화하면 먼저 모든 모델을 실행해요. 그 후 다음 태스크가 자동으로 실행돼요. 첫 번째 태스크가 실패하면 다음 태스크는 실행되지 않아요.

태스크 그래프에서 dbt 프로젝트 객체를 동시에 실행

태스크 그래프 분기는 같은 dbt 프로젝트 객체에 대해 같은 시간에 독립적인 데이터 슬라이스를 실행할 수 있어요. 다음 예시는 같은 루트 태스크 후에 시작하는 두 자식 태스크를 만들어요. 두 실행 모두 WRITEBACK=FALSE를 사용하므로 live 버전의 target 및 log 아티팩트를 업데이트하지 않아요:

-- 스케줄로 태스크 그래프 시작
CREATE OR ALTER TASK my_db.my_schema.run_dbt_slices
  WAREHOUSE = transform_wh
  SCHEDULE = '360 minutes'
  AS
    SELECT 1;

-- finance 데이터 슬라이스 실행
CREATE OR ALTER TASK my_db.my_schema.run_dbt_finance
  WAREHOUSE = transform_wh
  AFTER my_db.my_schema.run_dbt_slices
  AS
    EXECUTE DBT PROJECT my_db.my_schema.my_project
      ARGS = 'run --select tag:finance --target prod'
      WRITEBACK = FALSE;

-- sales 데이터 슬라이스를 동시에 실행
CREATE OR ALTER TASK my_db.my_schema.run_dbt_sales
  WAREHOUSE = transform_wh
  AFTER my_db.my_schema.run_dbt_slices
  AS
    EXECUTE DBT PROJECT my_db.my_schema.my_project
      ARGS = 'run --select tag:sales --target prod'
      WRITEBACK = FALSE;

-- 루트 태스크 전에 자식 태스크 다시 시작
ALTER TASK my_db.my_schema.run_dbt_finance RESUME;
ALTER TASK my_db.my_schema.run_dbt_sales RESUME;
ALTER TASK my_db.my_schema.run_dbt_slices RESUME;

루트 태스크가 실행되면 두 자식 태스크가 finance와 sales 데이터 슬라이스를 동시에 실행해요. Snowflake는 WRITEBACK 설정과 관계없이 쿼리별 결과 아티팩트와 아카이브를 저장해요. 검색 방법은 프로그래밍 방식으로 dbt 아티팩트와 로그 접근 문서를 참조하세요.

런타임에 동적 구성 전달

CONFIG로 태스크에 기본 구성을 저장한 다음 그 값들을 dbt 프로젝트의 환경 변수에 매핑해 태스크를 편집하지 않고 실행마다 변경할 수 있어요. ENV_VARS는 VARCHAR로 해결되는 {{ select ... }} 템플릿을 받아들이므로 SYSTEM$GET_TASK_GRAPH_CONFIG로 구성 값을 각 변수로 읽을 수 있어요:

CREATE OR ALTER TASK my_db.my_schema.run_dbt_configurable
  WAREHOUSE = transform_wh
  SCHEDULE = '360 minutes'
  CONFIG = $${"target_db": "analytics_prod", "run_date": "2026-07-01"}$$
AS
  EXECUTE DBT PROJECT my_db.my_schema.my_project
    ARGS = 'run --target prod'
    ENVIRONMENT = 'prod'
    ENV_VARS = (
      'DBT_TARGET_DB' = '{{ select SYSTEM$GET_TASK_GRAPH_CONFIG(\'target_db\')::string }}',
      'DBT_RUN_DATE' = '{{ select SYSTEM$GET_TASK_GRAPH_CONFIG(\'run_date\')::string }}'
    );

태스크를 수동으로 실행할 때 USING CONFIG를 전달해 그 단일 실행에 대한 기본값을 재정의해요. Snowflake는 동적 구성을 태스크의 기본 CONFIG에 병합하고 새 값이 SYSTEM$GET_TASK_GRAPH_CONFIG를 통해 dbt 프로젝트의 환경 변수로 흘러가요:

EXECUTE TASK my_db.my_schema.run_dbt_configurable
  USING CONFIG = $${"target_db": "analytics_dev", "run_date": "2026-07-15"}$$;

값은 높은 우선순위부터 해결돼요: EXECUTE DBT PROJECT의 ENV_VARS(또는 CLI의 --env-vars), 그다음 셸 변수(--use-shell-env-vars 사용 시), 그다음 env.yml의 활성 환경. env.yml 우선순위 규칙 전체는 값 우선순위 문서를 참조하세요.

Apache Airflow로 오케스트레이션

팀이 다른 파이프라인에 이미 Apache Airflow를 운영하고 있다면 dbt Projects on Snowflake를 기존 DAG에 통합할 수 있어요. 이 가이드는 Airflow를 예시로 사용하지만, 스케줄에 따라 Snowflake에 SQL을 발행할 수 있는 어떤 도구든 dbt 프로젝트 객체 실행을 오케스트레이션할 수 있어요.

Airflow를 언제 사용하는가

  • 팀이 다른 데이터 파이프라인에 이미 Airflow를 관리하고 있어요.
  • dbt 실행 또는 Snowflake 플랫폼이 더 큰 교차 시스템 워크플로의 한 단계예요(예: 외부 소스에서 데이터 수집 → dbt 실행 → 다운스트림 시스템 트리거).
  • 복잡한 분기나 외부 센서 같은 Airflow 특유의 기능이 필요해요.

팀이 dbt나 오케스트레이션을 막 시작했다면 Snowflake 태스크는 관리할 외부 인프라가 없는 더 단순한 옵션이에요.

사전 요구 사항

시작하기 전에 다음이 있는지 확인하세요:

  • Snowflake에 배포된 dbt 프로젝트 객체.
  • apache-airflow-providers-snowflake 패키지가 설치된 Apache Airflow.
  • account, user, 인증 자격 증명(프로덕션에는 키 쌍 권장), warehouse, database, schema, role로 Airflow에 구성된 Snowflake 연결.
  • Airflow 연결에 사용되는 역할은 dbt 프로젝트 객체에 EXECUTE DBT PROJECT 권한이 있어야 해요. 자세한 내용은 dbt Projects 접근 제어 문서를 참조하세요.

Airflow에서 Snowflake 연결 구성

Airflow 관리 패널이나 환경에서 Snowflake 연결을 설정할 때 다음 필드를 구성하세요:

  • Connection type: Snowflake
  • Account: Snowflake 계정 식별자(예: myorg-myaccount)
  • Login: 사용자 또는 서비스 계정 이름
  • Authentication: 프로덕션에는 키 쌍 인증을 권장해요. 비밀번호도 사용할 수 있어요.
  • Warehouse: EXECUTE DBT PROJECT 명령에 사용할 웨어하우스
  • Database: dbt 프로젝트 객체가 포함된 데이터베이스
  • Schema: dbt 프로젝트 객체가 포함된 스키마
  • Role: dbt 프로젝트 객체에 EXECUTE DBT PROJECT 권한이 있는 역할

💡 프로덕션 DAG에는 전용 서비스 계정(예: airflow_service_user)을 사용하세요. 이렇게 하면 태스크 권한이 한곳에서 거버넌스되고 팀원이 떠날 때 파이프라인이 깨지지 않아요.

옵션 1: SQLExecuteQueryOperator 사용 (권장)

Airflow Snowflake 공급자의 SQLExecuteQueryOperator는 Snowflake 연결을 통해 SQL 문을 직접 실행해요. 추가 CLI 설치가 필요 없는 SQL 연결만 필요하므로 가장 간단한 접근 방식이에요.

간단한 DAG: run 후 test

다음 DAG는 매일 오전 6시에 dbt 모델을 실행하고, 모델이 완료된 후 테스트를 실행해요:

from datetime import datetime
from airflow import DAG
from airflow.providers.common.sql.operators.sql import SQLExecuteQueryOperator

with DAG(
    dag_id="dbt_project_daily",
    start_date=datetime(2026, 1, 1),
    schedule="0 6 * * *",
    catchup=False,
    default_args={"conn_id": "snowflake_default"},
) as dag:
    run_models = SQLExecuteQueryOperator(
        task_id="dbt_run",
        sql="EXECUTE DBT PROJECT my_db.my_schema.my_project ARGS='run --target prod';",
    )
    run_tests = SQLExecuteQueryOperator(
        task_id="dbt_test",
        sql="EXECUTE DBT PROJECT my_db.my_schema.my_project ARGS='test --target prod';",
    )
    run_models >> run_tests
dbt 프로젝트 객체를 동시에 실행

다음 DAG는 같은 dbt 프로젝트 객체에서 두 개의 독립적인 데이터 슬라이스를 실행해요. 태스크 사이에 의존성이 없으므로 Airflow가 이들을 동시에 실행할 수 있어요. 두 실행 모두 WRITEBACK=FALSE를 사용하므로 live 버전의 target 및 log 아티팩트를 업데이트하지 않아요:

from datetime import datetime
from airflow import DAG
from airflow.providers.common.sql.operators.sql import SQLExecuteQueryOperator

with DAG(
    dag_id="dbt_project_concurrent_slices",
    start_date=datetime(2026, 1, 1),
    schedule="0 6 * * *",
    catchup=False,
    max_active_tasks=2,
    default_args={"conn_id": "snowflake_default"},
) as dag:
    run_finance = SQLExecuteQueryOperator(
        task_id="dbt_run_finance",
        sql=(
            "EXECUTE DBT PROJECT my_db.my_schema.my_project "
            "ARGS='run --select tag:finance --target prod' "
            "WRITEBACK = FALSE;"
        ),
    )
    run_sales = SQLExecuteQueryOperator(
        task_id="dbt_run_sales",
        sql=(
            "EXECUTE DBT PROJECT my_db.my_schema.my_project "
            "ARGS='run --select tag:sales --target prod' "
            "WRITEBACK = FALSE;"
        ),
    )

Snowflake는 WRITEBACK 설정과 관계없이 쿼리별 결과 아티팩트와 아카이브를 저장해요. 검색 방법은 프로그래밍 방식으로 dbt 아티팩트와 로그 접근 문서를 참조하세요.

ENV_VARS로 실행별 변수 전달

단일 실행에 대해 개별 변수를 재정의하려면 EXECUTE DBT PROJECT 문에 ENVIRONMENT와 ENV_VARS를 추가해요. Airflow는 {{data_interval_start}} 같은 매크로를 문을 Snowflake로 보내기 전에 런타임 값으로 대체해요:

from datetime import datetime
from airflow import DAG
from airflow.providers.common.sql.operators.sql import SQLExecuteQueryOperator

with DAG(
    dag_id="dbt_project_per_run_vars",
    start_date=datetime(2026, 1, 1),
    schedule="0 6 * * *",
    catchup=False,
    default_args={"conn_id": "snowflake_default"},
) as dag:
    run_models = SQLExecuteQueryOperator(
        task_id="dbt_run",
        sql=(
            "EXECUTE DBT PROJECT my_db.my_schema.my_project "
            "ARGS='run --target prod' "
            "ENVIRONMENT='prod' "
            "ENV_VARS=("
            "'DBT_RUN_START' = '{{ data_interval_start }}', "
            "'DBT_RUN_END' = '{{ data_interval_end }}');"
        ),
    )

Airflow가 런타임에 매크로를 대체하므로 Snowflake는 일반 문자열 값(예: 'DBT_RUN_START'='2026-07-15T00:00:00+00:00')을 받아요. 여기서 {{ select ... }} SQL 템플릿은 필요 없어요. 그 템플릿은 Snowflake 태스크 예시처럼 SYSTEM$GET_TASK_GRAPH_CONFIG 같은 소스에서 실행 시 값을 읽을 때만 사용해요. ENV_VARS 구문과 우선순위 규칙 전체는 dbt Projects on Snowflake용 SQL 환경 변수와 비공개 Git 패키지 사용 문서를 참조하세요.

센서 트리거 DAG: 업스트림 데이터 대기

다음 DAG는 S3 센서를 사용해 dbt 프로젝트를 실행하기 전에 외부 버킷에 파일이 도착할 때까지 기다려요. 수집 파이프라인에서 새 소스 데이터가 도착하거나 Iceberg 카탈로그 업데이트일 수 있어요. 팀은 Snowflake 태스크가 네이티브로 관찰할 수 없는 외부 시스템의 이벤트에 반응해야 할 때 Airflow 같은 외부 오케스트레이터를 선택하는 경우가 많아요.

from datetime import datetime
from airflow import DAG
from airflow.providers.amazon.aws.sensors.s3 import S3KeySensor
from airflow.providers.common.sql.operators.sql import SQLExecuteQueryOperator

with DAG(
    dag_id="dbt_project_sensor_triggered",
    start_date=datetime(2026, 1, 1),
    schedule="0 */2 * * *",
    catchup=False,
    default_args={"conn_id": "snowflake_default"},
) as dag:
    wait_for_file = S3KeySensor(
        task_id="wait_for_upstream_file",
        bucket_name="my-data-lake",
        bucket_key="incoming/events/{{ ds }}/data.parquet",
        aws_conn_id="aws_default",
        poke_interval=60,
        timeout=7200,
        mode="reschedule",  # poke 사이에 워커 슬롯 해제
    )
    run_models = SQLExecuteQueryOperator(
        task_id="dbt_run",
        sql="EXECUTE DBT PROJECT my_db.my_schema.my_project ARGS='run --target prod';",
    )
    run_tests = SQLExecuteQueryOperator(
        task_id="dbt_test",
        sql="EXECUTE DBT PROJECT my_db.my_schema.my_project ARGS='test --target prod';",
    )
    wait_for_file >> run_models >> run_tests

옵션 2: Snowflake CLI와 함께 BashOperator 사용

Snowflake CLI가 이미 Airflow 워커 환경에 설치되어 있다면 BashOperator를 사용해 snow dbt execute를 직접 호출할 수 있어요. 이 접근 방식은 --run-async 같은 CLI 네이티브 기능을 원할 때 유용해요.

📌 BashOperator 접근 방식은 Airflow 워커 환경에 Snowflake CLI 버전 3.13.0 이상이 필요해요. --connection 플래그는 ~/.snowflake/config.toml에 정의된 명명된 연결을 지정해요. 프로덕션에서는 빈 연결 뼈대(skeleton)만 커밋하고 SNOWFLAKE_CONNECTIONS_<NAME>_<PARAMETER> 형식을 사용해 환경 변수로 자격 증명을 공급하세요. 이들은 Snowflake CLI 연결 변수이며, env.yml에서 구성하는 dbt 프로젝트 환경 변수와는 다릅니다.

연결 정의에 대한 자세한 내용은 Snowflake 연결 관리 문서를 참조하세요.

기본 예시
from datetime import datetime
from airflow import DAG
from airflow.operators.bash import BashOperator

with DAG(
    dag_id="dbt_project_cli",
    start_date=datetime(2026, 1, 1),
    schedule="0 6 * * *",
    catchup=False,
) as dag:
    run_models = BashOperator(
        task_id="dbt_run",
        bash_command="snow dbt execute --connection prod_conn my_project run --target prod",
    )
    run_tests = BashOperator(
        task_id="dbt_test",
        bash_command="snow dbt execute --connection prod_conn my_project test --target prod",
    )
    run_models >> run_tests
--use-shell-env-vars로 셸 환경 변수 전달

Airflow 태스크가 이미 DBT_ 접두사 변수를 내보내거나, 실행별 Airflow 템플릿 값(예: 실행의 데이터 간격)이 정적 구성은 env.yml에 유지하면서 dbt로 흘러들어가길 원할 때 이 접근 방식을 사용하세요. 연산자에 DBT_ 접두사 env dict를 넘기고 snow dbt execute에 --use-shell-env-vars를 추가해요:

from datetime import datetime
from airflow import DAG
from airflow.operators.bash import BashOperator

with DAG(
    dag_id="dbt_project_cli_env_vars",
    start_date=datetime(2026, 1, 1),
    schedule="0 6 * * *",
    catchup=False,
) as dag:
    run_models = BashOperator(
        task_id="dbt_run",
        bash_command=(
            "snow dbt execute --use-shell-env-vars --connection prod_conn "
            "my_project run --target prod"
        ),
        env={
            "DBT_DATA_INTERVAL_START": "{{ data_interval_start }}",
            "DBT_DATA_INTERVAL_END": "{{ data_interval_end }}",
            "DBT_CURRENT_SCHEMA": "ANALYTICS_PROD",
        },
        append_env=True,
    )

실행이 시작되면 Snowflake CLI는 값이 높은 우선순위부터 해결해요: --env-vars, 그다음 --use-shell-env-vars가 가져오는 DBT_ 접두사 셸 변수, 그다음 프로젝트 env.yml의 활성 환경. 이 예시는 --env-vars를 전달하지 않으므로 Airflow 셸 변수가 env.yml의 일치하는 키보다 우선해요. 전체 구문과 우선순위 규칙은 dbt Projects on Snowflake용 SQL 환경 변수와 비공개 Git 패키지 사용 문서를 참조하세요.

📌 이 예시는 --use-shell-env-vars 플래그에 Snowflake CLI 3.21 이상이 필요해요. CLI는 DBT_ 접두사가 붙은 셸 변수만 읽어요(DBT_ENV_SECRET_* 제외). 연산자에 append_env=True를 설정해 태스크가 워커 환경을 상속하게 하세요. 이게 없으면 BashOperator는 하위 프로세스에 env dict만 전달하고, snow(및 SNOWFLAKE_CONNECTIONS_* 자격 증명)가 PATH에서 빠져요.

고려 사항

  • 서버리스 태스크는 dbt 프로젝트 객체를 실행할 수 없음: EXECUTE DBT PROJECT 명령을 실행하는 태스크를 만들 때는 웨어하우스를 지정해야 해요.
  • 두 역할 모델은 오케스트레이터와 관계없이 적용됨: 모든 EXECUTE DBT PROJECT 문은 호출 역할(태스크 소유자 또는 Airflow 연결 역할)과 dbt_projects_profiles.yml 또는 profiles.yml의 프로필 역할(dbt run이 접근할 수 있는 것을 제어)을 포함해요. 자세한 내용은 dbt Projects on Snowflake 모범 사례 문서의 오케스트레이션 섹션을 참조하세요.
  • 웨어하우스 구성 정렬: 태스크 정의(또는 Airflow 연결)와 dbt_projects_profiles.yml 또는 profiles.yml의 target에서 같은 웨어하우스를 사용하세요. 웨어하우스가 다르면 두 웨어하우스 모두 한 실행에 깨어나요.

더 알아보기 (Learn more)