Databricks Asset Bundle — Python Data Engineering - Databricks platform engineering / CI/CD reference implementation.
A practical Databricks Data Engineering project demonstrating how to develop, test, package, deploy, and execute Python workloads using Databricks Asset Bundles (DAB) and GitHub Actions CI/CD.
The project implements separate DEV and PROD environments, Python Wheel packaging, automated testing, parameterized Databricks Jobs, OAuth Service Principal authentication, and a reproducible development environment using VS Code Dev Containers.
GitHub Repository
│
┌───────────┴───────────┐
│ │
dev prod
│ │
▼ ▼
deploy_dev.yml deploy_prd.yml
│ │
▼ ▼
GitHub Actions GitHub Actions
│ │
┌─────┴─────┐ ┌─────┴─────┐
│ │ │ │
Tests Validate Validate Deploy
│ │ │ │
└─────┬─────┘ └─────┬─────┘
│ │
▼ ▼
DAB Bundle DAB Bundle
│ │
▼ ▼
Databricks DEV Databricks PROD
│ │
└───────────┬───────────┘
│
▼
dab_test_job
│
▼
demo_notebook.py
│
▼
Unity Catalog
catalog.schema.users
This project is based on the Databricks Asset Bundle default Python project structure and has been extended to demonstrate a more complete Data Engineering deployment workflow.
The main workload demonstrates:
- Python application development.
- Databricks notebook execution.
- Parameterized Databricks Jobs.
- Python Wheel packaging.
- Databricks Asset Bundle configuration.
- DEV and PROD environments.
- Automated testing.
- GitHub Actions CI/CD.
- OAuth Service Principal authentication.
- Containerized local development.
| Technology | Purpose |
|---|---|
| Python 3.10–3.12 | Application development |
| PySpark | Distributed data processing |
| Databricks | Data Engineering platform |
| Databricks Asset Bundles | Deployment and resource management |
| Databricks CLI | Bundle validation, deployment and execution |
| Unity Catalog | Catalog/schema/table organization |
| uv | Python dependency management and build |
| Hatchling | Python Wheel build backend |
| Pytest | Automated testing |
| Ruff | Python linting |
| GitHub Actions | CI/CD |
| Docker | Development environment |
| VS Code Dev Containers | Reproducible development environment |
| YAML | Databricks and CI/CD configuration |
| TOML | Python project configuration |
.
├── .devcontainer/
│ ├── .env
│ ├── Dockerfile
│ ├── devcontainer.json
│ └── requirements.txt
│
├── .github/
│ └── workflows/
│ ├── deploy_dev.yml
│ └── deploy_prd.yml
│
├── dab_test/
│ ├── .vscode/
│ │
│ ├── fixtures/
│ │
│ ├── resources/
│ │ └── jobs/
│ │ └── dab_test_job.yml
│ │
│ ├── src/
│ │ ├── dab_test/
│ │ │ ├── __init__.py
│ │ │ └── main.py
│ │ │
│ │ └── notebooks/
│ │ └── demo_notebook.py
│ │
│ ├── tests/
│ │ ├── job_config_test.py
│ │ └── main_test.py
│ │
│ ├── AGENTS.md
│ ├── CLAUDE.md
│ ├── README.md
│ ├── databricks.yml
│ └── pyproject.toml
│
└── README.md
The core of the project is the databricks.yml file.
The Bundle is named:
bundle:
name: dab_testThe configuration includes resource definitions from:
resources/jobs/*.yml
resources/pipelines/*.yml
resources/schemas/*.yml
It also defines a Python Wheel artifact:
artifacts:
python_artifact:
type: whl
build: uv build --wheelThis means the deployment process can build the Python application into a .whl package and make it available to the Databricks workload.
The project defines two Databricks Bundle targets.
The dev target uses:
mode: developmentand is the default Bundle target.
It uses the following configuration:
Catalog: dev
Schema: rescue_b
The DEV workflow is intended for development, testing, validation, deployment, and execution.
The prod target uses:
mode: productionwith:
Catalog: prod
Schema: rescue_b
The production deployment is associated with the prod Git branch.
The production workflow can be triggered by:
- a push to the
prodbranch; - manual GitHub Actions execution.
The main Python package is located under:
dab_test/src/dab_test/
The main application contains a simple Spark workload that reads the Databricks sample NYC Taxi dataset:
def find_all_taxis() -> DataFrame:
return spark.read.table("samples.nyctaxi.trips")The main() function displays the first five records.
The project therefore provides a minimal Python/Spark workload that can be packaged and executed through the Databricks environment.
The project also contains:
dab_test/src/notebooks/demo_notebook.py
The notebook demonstrates parameterized Databricks execution using widgets:
catalog
user_id
user_name
The notebook:
- Receives runtime parameters.
- Creates a
userstable if it does not exist. - Inserts sample users.
- Inserts the parameterized user.
- Reads the resulting table.
- Displays the resulting DataFrame.
The target table follows the pattern:
<catalog>.rescue_b.users
For example:
dev.rescue_b.users
prod.rescue_b.users
The Job is defined in:
dab_test/resources/jobs/dab_test_job.yml
The Job is called:
dab_test_job
It contains a task named:
ingestao_usuarios
which executes:
src/notebooks/demo_notebook.py
The Job exposes parameters including:
catalog_name
user_id
user_name
This allows the same notebook to be reused with different runtime values instead of hard-coding the input data.
The Job configuration defines a Quartz cron schedule:
Every Tuesday at 08:00
Timezone: America/Sao_Paulo
The Job also has a timeout of:
900 seconds
Failure notifications are configured through Databricks Job email notifications.
One of the main concepts demonstrated by this project is the separation between:
Defined in:
databricks.yml
Example:
catalog
schema
catalog_name
performance_target
and:
Defined in:
resources/jobs/dab_test_job.yml
Example:
catalog_name
user_id
user_name
The values can flow through the deployment configuration into the notebook at runtime.
Conceptually:
databricks.yml
│
│ ${var.catalog_name}
▼
Databricks Job
│
│ {{job.parameters.catalog_name}}
▼
demo_notebook.py
│
▼
Unity Catalog
The Python project is configured through:
dab_test/pyproject.toml
The project supports:
Python >= 3.10
Python < 3.13
The build system uses:
Hatchling
The Wheel package is built using:
uv build --wheelThe resulting package can be used by the Databricks deployment.
The project includes development dependencies for:
- Pytest
- Ruff
- PyYAML
- Databricks DLT
- Databricks Connect
- IPython Kernel
Install the development dependencies using:
uv sync --devTests are located under:
dab_test/tests/
Current test modules include:
main_test.py
job_config_test.py
Run the tests locally with:
uv run pytestThe DEV CI/CD workflow also executes:
uv run pytest -sbefore Bundle validation and deployment.
The repository contains two GitHub Actions workflows:
.github/workflows/
├── deploy_dev.yml
└── deploy_prd.yml
The DEV workflow is triggered by pushes to:
dev
It performs:
Checkout
│
▼
Install Databricks CLI
│
▼
Install uv
│
▼
Configure Databricks OAuth
│
▼
Run Pytest
│
▼
Validate Bundle
│
▼
Deploy Bundle
│
▼
Run Databricks Job
The production workflow is triggered by:
push to prod
or manually through:
workflow_dispatch
The production workflow performs:
Checkout
│
▼
Install Databricks CLI
│
▼
Install uv
│
▼
Configure PROD OAuth Service Principal
│
▼
Validate Bundle
│
▼
Deploy Bundle
│
▼
Run Databricks Job
The PROD workflow deploys using:
databricks bundle deploy --target prodand executes:
databricks bundle run dab_test_job --target prodGitHub Actions authenticates to Databricks using an OAuth Service Principal.
The workflows obtain the following values from GitHub Secrets:
DATABRICKS_HOST
DATABRICKS_CLIENT_ID
DATABRICKS_CLIENT_SECRET
Environment-specific secrets are used for DEV and PROD.
For example:
DATABRICKS_HOST_DEV
DATABRICKS_CLIENT_ID_DEV
DATABRICKS_CLIENT_SECRET_DEV
and:
DATABRICKS_HOST_PRD
DATABRICKS_CLIENT_ID_PRD
DATABRICKS_CLIENT_SECRET_PRD
No credentials should be committed to the repository.
Recommended tools:
- Git
- Docker
- Visual Studio Code
- VS Code Dev Containers extension
- Python 3.10–3.12
- uv
- Databricks CLI
The project provides a development container under:
.devcontainer/
with:
Dockerfile
devcontainer.json
requirements.txt
.env
Open the repository in VS Code and select:
Dev Containers: Reopen in Container
This provides a reproducible development environment.
Never commit production credentials, access tokens, client secrets, or other sensitive information to
.envor the repository.
Authenticate to Databricks using your preferred authentication method.
For a local profile:
databricks configureVerify the CLI:
databricks --versionFrom the project directory:
cd dab_testValidate DEV:
databricks bundle validate --target devValidate PROD:
databricks bundle validate --target prodValidation should be performed before deployment.
cd dab_test
databricks bundle deploy --target devAfter deployment, execute the Job:
databricks bundle run dab_test_job --target devProduction deployment should preferably occur through the GitHub Actions workflow.
The equivalent CLI commands are:
cd dab_test
databricks bundle validate --target prod
databricks bundle deploy --target prod
databricks bundle run dab_test_job --target prodThe complete workflow is:
Developer
│
│ git push
▼
GitHub
│
├───────────────┐
│ │
dev prod
│ │
▼ ▼
DEV Workflow PROD Workflow
│ │
▼ ▼
Pytest Validation
│ │
▼ ▼
Validation Deployment
│ │
▼ ▼
Deployment Job Execution
│ │
▼ ▼
Databricks DEV Databricks PROD
Defines the Databricks Asset Bundle.
Responsible for:
- Bundle name
- Resources
- Variables
- Artifacts
- DEV target
- PROD target
- Workspace configuration
Defines the Python project.
Responsible for:
- Python version
- Project metadata
- Dependencies
- Development dependencies
- Entry point
- Build system
- Wheel packaging
- Ruff configuration
Defines the Databricks Job.
Responsible for:
- Job name
- Job parameters
- Schedule
- Timeout
- Notifications
- Notebook task
- Runtime parameters
- Performance configuration
Defines the DEV CI/CD pipeline.
Responsible for:
- Installing tooling
- Authentication
- Running tests
- Bundle validation
- Deployment
- Job execution
Defines the PROD CI/CD pipeline.
Responsible for:
- Installing tooling
- PROD authentication
- Bundle validation
- Production deployment
- Job execution
This project demonstrates the following Data Engineering and DevOps practices:
Databricks resources are defined as code rather than being created manually through the Databricks UI.
The same Bundle supports:
DEV
PROD
using different targets.
The application is packaged as a Python Wheel before deployment.
Pytest is integrated into the DEV deployment pipeline.
GitHub Actions automates the deployment lifecycle.
The Databricks Job passes runtime parameters into the notebook.
CI/CD uses OAuth-based Service Principal authentication rather than personal credentials.
The Dev Container provides a consistent development environment.
Current implementation:
- Databricks Asset Bundle
- Python project structure
- PySpark application
- Databricks notebook
- Parameterized Databricks Job
- Unity Catalog catalog/schema configuration
- DEV target
- PROD target
- Python Wheel packaging
- uv dependency management
- Hatchling build system
- Pytest tests
- Ruff configuration
- VS Code Dev Container
- GitHub Actions DEV pipeline
- GitHub Actions PROD pipeline
- Databricks OAuth Service Principal authentication
- Automated Databricks Job execution
Potential extensions include:
- Add Delta Lake ingestion and transformation layers
- Add Bronze/Silver/Gold architecture
- Add data quality validation
- Add integration tests against Databricks
- Add structured logging
- Add monitoring and alerting
- Add Unity Catalog permissions management
- Add CI quality gates for Ruff
- Add pull-request validation
- Add deployment approval gates for PROD
- Add infrastructure documentation
- Add job run monitoring
- Add data lineage documentation
This project was created to demonstrate practical knowledge of:
Python
│
├── Packaging
├── Testing
└── PySpark
│
▼
Databricks
│
├── Asset Bundles
├── Jobs
├── Notebooks
└── Unity Catalog
│
▼
DevOps
│
├── Git
├── GitHub Actions
├── CI/CD
└── Service Principal
The main objective is to demonstrate how a Data Engineering workload can move from local development to a controlled production deployment using modern software engineering practices.
Ruben Cruz
Data Engineering · Data Integration · Python · PySpark · Databricks · CI/CD