dbt-aws¶
Run dbt projects on AWS Glue (Spark Jobs, Interactive Sessions, Python Shell) and Amazon EMR (Serverless, on-EC2) — orchestrated from Apache Airflow (including MWAA).
One library, five runner shapes, declarative routing, visual grouping, and worker-side dbt package installs so your Airflow deployment stays lean.
PyPI distribution:
runner-dbt-aws-airflow· Python import:import dbt_aws· Repo: https://github.com/awslabs/runner-dbt-aws-airflow
Why runner-dbt-aws-airflow¶
- One DAG, multiple compute backends. Route bronze to a Glue Spark Job, silver/gold to a warm Glue Interactive Session, tiny Athena transforms to Glue Python Shell — from one Airflow DAG, without hand-rolling five operators.
- Declarative YAML routing.
overrides[tag.<name>]andoverrides[model.<uid>]bulk-route or per-model-tweak every knob the runner exposes (worker type, timeout,--vars, profile, target,resource_tags, ...). - Lean MWAA
requirements.txt. Workers installdbt-core+ adapter (dbt-spark,dbt-duckdb,dbt-athena, ...) at task-run time via--additional-python-modulesor EMR bootstrap. MWAA never needsdbt-corein its own requirements. - AWS resource tags. Top-level
resource_tags:cascades to every runner (Glue Job, Glue Session, EMR application). Per-tag / per-model overrides layer on top. - IAM-first security posture. The Glue / EMR worker
authenticates to AWS via its IAM instance / task role. The dbt
profiles.ymlis a plain adapter connection profile (type: spark, method: session) and carries no credentials. - OpenLineage + SageMaker Unified Studio. Opt-in emission of
START/COMPLETEevents to S3 (NDJSON) or SMUS (datazone:PostLineageEvent). Multi-runner DAGs collapse into one lineage graph via a shared parent facet. - Task-collapse. Fold view+consumer chains and ephemeral drops into a single Airflow task. Proven with Glue 5.1 + native Iceberg + materialised views.
- Cosmos-compatible API.
DbtDag/DbtTaskGroupaccept the standardProjectConfigshape.
Runner shapes¶
| Runner | Backend |
|---|---|
GlueSparkRunner |
AWS Glue Spark Job |
GlueInteractiveSessionRunner |
AWS Glue Interactive Session (warm or per-node) |
GluePythonShellRunner |
AWS Glue Python Shell (Glue 3.0, 1 DPU) |
EmrServerlessRunner |
Amazon EMR Serverless |
EmrClusterStepRunner |
Amazon EMR-on-EC2 cluster step |
Verified end-to-end¶
All five runners were exercised against real AWS in us-east-1
using runner-dbt-aws-airflow 1.0.0; Glue 6.0 additionally passed
with dbt-core 1.12.3 + dbt-spark[session] 1.11.0. See
Reference → compat
for the full table.
Quick links¶
-
Get started in 5 minutes
Wire your first dbt project to a Glue Spark Job runner and run it from Airflow. Complete sample project + DAG.
-
Concepts
Architecture, runner shapes, routing, task-collapse, OpenLineage, MWAA deployment.
-
Reference
DbtDag/DbtTaskGroupAPI, full YAML schema, override fields, compatibility matrix. -
How-to
Recipe-style guides: MWAA quickstart, route by tag, multi-runner mix, OpenLineage.
Install¶
pip install runner-dbt-aws-airflow
# With Airflow + provider extras
pip install "runner-dbt-aws-airflow[airflow]"
# With OpenLineage emission
pip install "runner-dbt-aws-airflow[lineage]"
The Python import path stays dbt_aws (PEP 420 namespace package)
— only the PyPI distribution + CLI name follow the repo:
from dbt_aws.common.builder import DbtDag, DbtTaskGroup
from dbt_aws.common import ProjectConfig, load_runner_config
Two deployment variants (pick the one that matches your networking)¶
| Variant | Workers have internet? | MWAA needs dbt-core? |
Where dbt deps runs |
|---|---|---|---|
| A (most users) | Yes | No | On the worker, in /tmp/<run-id>/project/dbt_packages/ |
| B (air-gapped) | No | Yes | On the Airflow scheduler; dbt_packages/ baked into the archive |
Variant A is the default. MWAA requirements.txt needs only the
runner-dbt-aws-airflow wheel; workers install packages.yml deps
themselves at task-run time. The library does not import dbt anywhere
at DAG-parse time (manifest.json is parsed as plain JSON), so DAG
parse can't fail with ModuleNotFoundError even when dbt-core
isn't installed on the scheduler.
Variant B applies when workers can't reach the internet (private subnets with only VPC endpoints, corporate egress firewalls). See Concepts → Deployment → Two deployment variants for the switch.