Getting started¶
Wire a dbt project to a Glue Spark Job runner and run it from Airflow (locally or on MWAA). Copy-paste-and-run.
Prerequisites¶
- An AWS account with permissions to create Glue Jobs, read/write an S3 bucket, and assume an IAM role.
- An IAM role Glue can assume with
AWSGlueServiceRole+ read/write on your project bucket. - Airflow 2.9+ or 3.x. MWAA 3.2.1 is the recommended managed runtime; see How-to → MWAA quickstart for the end-to-end deploy walkthrough.
- Python 3.10-3.12 in the Airflow scheduler venv (for local dev).
1. Install¶
pip install runner-dbt-aws-airflow
# With Airflow + AWS provider extras
pip install "runner-dbt-aws-airflow[airflow]"
Or in a uv-managed project:
The Python import path stays dbt_aws (PEP 420 namespace package):
from dbt_aws.common import ProjectConfig, load_runner_config
from dbt_aws.common.builder import DbtDag
from dbt_aws.spark.runners import GlueSparkRunner
2. Sample dbt project¶
Minimum shape — one seed, one model, dbt-spark on the Glue
worker (both locally via the session method and on Glue):
my_dbt_project/
├── dbt_project.yml
├── profiles.yml
├── seeds/
│ └── raw_orders.csv
└── models/
└── stg_orders.sql
dbt_project.yml:
name: my_dbt_project
version: '1.0.0'
config-version: 2
profile: my_dbt_project
seeds:
my_dbt_project:
+schema: raw
models:
my_dbt_project:
+materialized: table
+schema: analytics
profiles.yml — dbt adapter connection profile. Carries no
credentials; the Glue worker authenticates to AWS via its IAM role
and dbt-spark's session method binds to the SparkSession the
Glue runtime already provides:
seeds/raw_orders.csv:
id,customer_id,order_total,ordered_at
1,10,100.00,2026-01-01
2,20,200.00,2026-01-02
3,30,300.00,2026-01-03
models/stg_orders.sql:
{{ config(tags=['bronze']) }}
select
id,
customer_id,
order_total,
ordered_at
from {{ ref('raw_orders') }}
where order_total > 0
3. Generate your dbt manifest¶
The library reads the dbt graph from target/manifest.json.
Regenerate it whenever the project changes:
Commit target/manifest.json alongside the DAG, or produce it in
your CI before syncing DAGs to S3.
4. Wire the DAG¶
Drop this into your Airflow dags_folder:
5. Trigger it¶
Locally:
MWAA: sync the DAG file + manifest.json to your MWAA S3 bucket
and trigger from the Airflow UI. See
How-to → MWAA quickstart for the
step-by-step.
What happens on trigger:
- Airflow imports the DAG file.
build_and_upload_project_archiveuploads the dbt project archive tos3://<bucket>/dbt-aws/archives/<sha256>.tar.gz(idempotent). - Each model / seed / test in
manifest.jsonbecomes an Airflow task, wired bydepends_on. - Each task:
glue:CreateJob(orUpdateJobif it exists) →glue:StartJobRun→airflow.deferon a custom trigger that polls the Glue Job run state. - On the Glue worker:
pip install runner-dbt-aws-airflow==1.0.0 dbt-core==1.11.11 dbt-spark[session]==1.9.3, download the archive, rundbt run --select <model_name>.
You'll see one log link per task pointing at the Glue Job run page in the AWS console.
6. Alternative install paths¶
For Glue 6.0 (Python 3.13, Spark 4.1.1), swap the install string to:
and set glue_version="6.0" on the runner.
For Glue Python Shell 3.0, PyPI isn't reachable from the worker — mirror the wheel to S3 and reference it there. See Reference → compat for the full version matrix.
Next steps¶
- Concepts → Runners — the five runner shapes and when to pick each.
- Concepts → Routing — per-tag / per-node routing via
overrides:. - How-to → MWAA quickstart — end-to-end MWAA deployment.
- How-to → Multi-runner mix — different dbt layers on different backends.
- Reference → YAML config — declare runners in a
.ymlfile instead of Python.