The DAB Readiness Blueprint: From Zero to First Green Pipeline in a Day
This guide walks through setting up your first Databricks Asset Bundle—from prerequisites to a working CI/CD pipeline.
What You’ll Learn & Why DABs Matter Now
Databricks Asset Bundles (DABs) represent a paradigm shift in how we deploy and manage Databricks workloads. Instead of manually configuring jobs through the UI or maintaining fragile deployment scripts, DABs provide:
- Infrastructure as Code for all Databricks resources
- Environment parity across dev, QA, and production
- Git-native workflows with branch-based deployments
- Reproducible deployments that eliminate “works on my cluster” issues
The timing is critical. As data teams scale, the gap between ad-hoc notebook development and production-grade engineering widens. DABs bridge that gap with minimal overhead.
Readiness Signals
Before diving into bundle configuration, assess your organization’s readiness across three dimensions.
Versioned Codebase
Your code must live in version control. This seems obvious, but many data teams still operate with notebooks as the source of truth.
Minimum requirements:
- Git repository (GitHub, GitLab, Azure DevOps)
- Branching strategy defined (GitFlow, trunk-based, or similar)
- Code review process established
- Basic test coverage for critical transformations
# Verify your repo structure
my-databricks-project/
├── src/
│ ├── pipelines/
│ │ ├── bronze/
│ │ ├── silver/
│ │ └── gold/
│ └── utils/
├── tests/
│ └── unit/
├── databricks.yml
└── README.md
Environments
You need clearly defined environments with corresponding Databricks workspaces.
| Environment | Purpose | Databricks Workspace |
|---|---|---|
| dev | Individual development | dev-workspace.cloud.databricks.com |
| qa | Integration testing | qa-workspace.cloud.databricks.com |
| prod | Production workloads | prod-workspace.cloud.databricks.com |
Each environment should have its own Unity Catalog, secret scopes, and cluster policies configured.
Secrets & Cluster Policies
Two often-overlooked prerequisites that block first deployments:
Secret Scopes: Store credentials for external systems (databases, APIs, storage accounts).
# Create a secret scope (one-time setup per workspace)
databricks secrets create-scope --scope my-project-secrets
# Add secrets
databricks secrets put --scope my-project-secrets --key storage-account-key
Cluster Policies: Define guardrails for compute resources. Without policies, DABs can’t create clusters.
{
"spark_version": {
"type": "fixed",
"value": "14.3.x-scala2.12"
},
"node_type_id": {
"type": "allowlist",
"values": ["Standard_DS3_v2", "Standard_DS4_v2"]
},
"autoscale.min_workers": {
"type": "range",
"minValue": 1,
"maxValue": 4
}
}
The Minimal DAB Skeleton
databricks.yml Anatomy
The databricks.yml file is the heart of your bundle. Here’s the 80/20 configuration that covers most use cases:
bundle:
name: my-data-pipeline
variables:
catalog:
description: Unity Catalog name
default: dev_catalog
schema:
description: Schema for pipeline tables
default: bronze
targets:
dev:
mode: development
default: true
workspace:
host: https://dev-workspace.cloud.databricks.com
variables:
catalog: dev_catalog
qa:
workspace:
host: https://qa-workspace.cloud.databricks.com
variables:
catalog: qa_catalog
prod:
mode: production
workspace:
host: https://prod-workspace.cloud.databricks.com
variables:
catalog: prod_catalog
run_as:
service_principal_name: prod-deployer-sp
resources:
jobs:
daily_ingestion:
name: "[${bundle.target}] Daily Data Ingestion"
schedule:
quartz_cron_expression: "0 0 6 * * ?"
timezone_id: UTC
tasks:
- task_key: bronze_load
notebook_task:
notebook_path: ./src/pipelines/bronze/ingest.py
new_cluster:
spark_version: 14.3.x-scala2.12
node_type_id: Standard_DS3_v2
num_workers: 2
spark_conf:
spark.databricks.catalog: ${var.catalog}
Key points:
- bundle.name: Unique identifier for your project
- variables: Parameterize everything that differs between environments
- targets: Define per-environment configurations
- resources: Declare your jobs, pipelines, and experiments
Resource Types
DABs support multiple resource types. Choose based on your use case:
| Resource Type | Use Case | Declaration |
|---|---|---|
jobs | Scheduled or triggered workflows | resources.jobs |
pipelines | Delta Live Tables | resources.pipelines |
experiments | MLflow experiments | resources.experiments |
models | MLflow model registry | resources.models |
schemas | Unity Catalog schemas | resources.schemas |
Local to Remote Loop
CLI Commands
The Databricks CLI provides three essential commands for the development loop:
# Validate bundle syntax and configuration
databricks bundle validate
# Deploy resources to target workspace
databricks bundle deploy --target dev
# Run a specific job or pipeline
databricks bundle run --target dev daily_ingestion
The typical development workflow:
- Make changes to code or configuration
databricks bundle validate- catch errors earlydatabricks bundle deploy --target dev- push to dev workspacedatabricks bundle run --target dev job_name- test execution- Review logs and iterate
Target-Driven Parameters
Leverage variables to avoid branch-specific YAML. Never hardcode environment-specific values:
variables:
storage_account:
description: Azure Storage Account
container:
description: Container name
targets:
dev:
variables:
storage_account: devstorageacct
container: raw-dev
prod:
variables:
storage_account: prodstorageacct
container: raw-prod
resources:
jobs:
ingestion:
tasks:
- task_key: load
notebook_task:
notebook_path: ./src/ingest.py
base_parameters:
storage_path: "abfss://${var.container}@${var.storage_account}.dfs.core.windows.net/"
This approach means the same databricks.yml works across all environments without modification.
CI Fast Path
GitHub Actions Workflow
Here’s a production-ready GitHub Actions workflow that validates on PR and deploys on merge:
name: DAB CI/CD
on:
pull_request:
branches: [main]
push:
branches: [main]
env:
DATABRICKS_HOST: ${{ secrets.DATABRICKS_HOST }}
DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN }}
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Databricks CLI
run: |
curl -fsSL https://raw.githubusercontent.com/databricks/setup-cli/main/install.sh | sh
- name: Validate Bundle
run: databricks bundle validate
- name: Run Tests
run: |
pip install pytest
pytest tests/ -v
deploy-qa:
needs: validate
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: qa
steps:
- uses: actions/checkout@v4
- name: Install Databricks CLI
run: |
curl -fsSL https://raw.githubusercontent.com/databricks/setup-cli/main/install.sh | sh
- name: Deploy to QA
run: databricks bundle deploy --target qa
- name: Run Smoke Tests
run: databricks bundle run --target qa smoke_test_job
deploy-prod:
needs: deploy-qa
runs-on: ubuntu-latest
environment: prod
steps:
- uses: actions/checkout@v4
- name: Install Databricks CLI
run: |
curl -fsSL https://raw.githubusercontent.com/databricks/setup-cli/main/install.sh | sh
- name: Deploy to Production
run: databricks bundle deploy --target prod
Artifact & Promotion Strategy
For more complex deployments, consider artifact-based promotion:
- Build Phase: Package your Python code as a wheel
- Publish Phase: Upload to an artifact repository (Nexus, Azure Artifacts) or simply store in a Unity Catalog Volume—the easiest option
- Deploy Phase: Reference versioned artifacts in your bundle
resources:
jobs:
production_pipeline:
tasks:
- task_key: transform
python_wheel_task:
package_name: my_transforms
entry_point: main
libraries:
- whl: /Volumes/prod_catalog/artifacts/my_transforms-1.2.0-py3-none-any.whl
This decouples deployment from code changes, enabling rollbacks by simply redeploying a previous artifact version.
Troubleshooting First Run
Here are the top 5 errors teams encounter on their first DAB deployment:
1. Authentication Failure
Error: Error: cannot configure default credentials
Fix: Ensure your authentication is configured. For local development, use OAuth (recommended):
databricks auth login --host https://your-workspace.cloud.databricks.com
For CI/CD, use a service principal with DATABRICKS_HOST and DATABRICKS_CLIENT_ID/DATABRICKS_CLIENT_SECRET environment variables, or DATABRICKS_TOKEN for simpler setups.
2. Missing Cluster Policy
Error: INVALID_PARAMETER_VALUE: Cluster policy not found
Fix: Create a cluster policy in your workspace and reference it:
new_cluster:
policy_id: E0123456789ABCDEF
3. Permission Denied on Secrets
Error: PERMISSION_DENIED: User does not have permission to access secret scope
Fix: Grant READ permission on the secret scope:
databricks secrets put-acl --scope my-scope --principal users --permission READ
4. Invalid Notebook Path
Error: RESOURCE_DOES_NOT_EXIST: Notebook not found
Fix: Paths are relative to bundle root. Verify:
- Notebook exists at specified path
- File extension is correct (
.py, not.ipynb) - Path starts with
./for relative paths
5. Variable Not Defined for Target
Error: Variable 'catalog' is not defined for target 'prod'
Fix: Ensure all required variables have values for each target:
targets:
prod:
variables:
catalog: prod_catalog # Don't forget this!