Study guide

11.1 Databricks Asset Bundles (DABs) & Infrastructure as Code

Databricks Certified Data Engineer Professional Exam

Track your progress as you read

Finished sections get a check mark.

1 Chapter 1: Developing Code for Data Processing using Python and SQL - Core Spark SQL & PySpark

1.1 Complex PySpark Transformations & DataFrame API 1.2 Advanced Spark SQL Patterns 1.3 Streaming Workloads with Structured Streaming 1.4 Lakeflow & Delta Live Tables (DLT) Declarative Pipelines

2 Chapter 2: Developing Code for Data Processing using Python and SQL - Streaming & Advanced Patterns

2.1 Advanced Delta Lake Features 2.2 Custom & Stateful Streaming Operations 2.3 Python & PySpark Code Modularization 2.4 User-Defined Functions (UDFs) & Performance Impact

3 Chapter 3: Data Ingestion & Acquisition

3.1 Auto Loader (cloudFiles) Production Ingestion 3.2 Change Data Capture (CDC) Ingestion Patterns 3.3 Batch & Streaming Connectors

4 Chapter 4: Data Transformation, Cleansing, and Quality

4.1 Data Validation & Quality Frameworks 4.2 Data Cleansing, Deduplication & Standardization 4.3 Silver and Gold Medallion Layer Refinement 4.4 Handling Schema Drift and Evolution

5 Chapter 5: Data Sharing and Federation

5.1 Delta Sharing Architecture & Governance 5.2 Lakehouse Federation

6 Chapter 6: Monitoring and Alerting & Observability

6.1 System Tables & Observability 6.2 Databricks Workflows & Job Monitoring 6.3 Spark UI & Query Execution Diagnostics 6.4 Data Quality & Pipeline Alerting

7 Chapter 7: Cost & Performance Optimisation - Data Layout & Compute

7.1 Data Storage & Layout Optimization 7.2 Compute Choice & Cluster Sizing 7.3 Photon Engine & Query Acceleration

8 Chapter 8: Cost & Performance Optimisation - Skew & Cost Governance

8.1 Partitioning & Data Skew Remediation 8.2 Cost Governance & DBU Optimization

9 Chapter 9: Ensuring Data Security and Compliance

9.1 Unity Catalog Access Control & Least Privilege 9.2 Dynamic Data Masking & Row/Column-Level Security 9.3 Secrets Management & Network Security 9.4 Compliance, Audit & Data Privacy

10 Chapter 10: Data Governance in Unity Catalog

10.1 Unity Catalog Governance Architecture 10.2 Data Lineage & Tagging in Unity Catalog 10.3 Managed vs External Tables & Storage Governance

11 Chapter 11: Debugging and Deploying - Asset Bundles & CI/CD

11.1 Databricks Asset Bundles (DABs) & Infrastructure as Code 11.2 CI/CD Automation & Databricks CLI / REST API 11.3 Troubleshooting Pipeline & Job Failures 11.4 Code Versioning & Databricks Git Integration

12 Chapter 12: Data Modelling & Lakehouse Analytics

12.1 Medallion Architecture Design Patterns 12.2 Dimensional Modeling in the Lakehouse 12.3 Analytics & BI Optimization

11.1 Databricks Asset Bundles (DABs) & Infrastructure as Code

Key Takeaways Explain This Topic AI

Databricks Asset Bundles (DABs) use a databricks.yml file to define infrastructure as code, supporting structured deployment of jobs, pipelines, and artifacts.

Target environments (e.g., dev, staging, prod) are declared within bundle.yml or databricks.yml to ensure strict separation of configurations across workspaces.

The databricks bundle validate command parses the bundle configuration for syntax errors and structural validity without performing a deployment.

Running databricks bundle deploy synchronizes local files to the target Databricks workspace and updates resource definitions like jobs or DLT pipelines.

Databricks bundles can substitute variables and environment-specific parameters dynamically, allowing DRY (Don't Repeat Yourself) infrastructure configurations.

Last updated: July 2026

Databricks Asset Bundles (DABs) fundamentally shift how data engineering teams manage their Databricks infrastructure, moving from manual UI-based configurations to a robust Infrastructure-as-Code (IaC) methodology. This section explores the structural, operational, and lifecycle aspects of DABs, which are a major focus area for the Databricks Certified Data Engineer Professional exam.

The Anatomy of Databricks Asset Bundles

At its core, a Databricks Asset Bundle is a collection of source files and a centralized configuration file, typically named databricks.yml (or occasionally bundle.yml ), that describes how these files should be deployed and executed in a Databricks workspace. By treating Databricks resources (like Jobs, Delta Live Tables pipelines, and Model Serving endpoints) as code, DABs enable version control, automated testing, and CI/CD integration. This paradigm shift from manual click-ops to programmatic deployment ensures that environments can be easily recreated, audited, and rolled back if necessary. The bundle directory structure usually contains the databricks.yml at the root, a src directory for code (like Python scripts, notebooks, or SQL files), a tests directory for unit and integration testing, and a resources directory for modularized YAML definitions if the project is large.

The databricks.yml Structure

The databricks.yml file is the heart of a DAB. It defines the bundle's name, its target environments, the resources it manages, and any workspace variables. Here is a comprehensive example of a databricks.yml file: bundle:

name: my_etl_project

variables:

catalog_name:

  • description: "The catalog to use for deployment"
  • default: "dev_catalog"

targets:

dev:

default: true

workspace:

host: https://adb-123456789.1.azuredatabricks.net

variables:

catalog_name: "dev_catalog"

prod:

workspace:

host: https://adb-987654321.2.azuredatabricks.net

variables:

catalog_name: "prod_catalog"

resources:

jobs:

daily_etl:

name: "[${bundle.target}] Daily ETL Job"

tasks:

- task_key: process_data

notebook_task:

  • notebook_path: ./src/process.py
  • job_cluster_key: default_cluster

job_clusters:

- job_cluster_key: default_cluster

new_cluster:

  • spark_version: 14.3.x-scala2.12
  • node_type_id: i3.xlarge
  • num_workers: 2

In this example, the bundle dynamically adapts based on the target environment. The ${bundle.target} syntax is a bundle variable substitution that dynamically injects the target name (e.g., dev or prod ) into the job name. Furthermore, Databricks bundles can integrate deeply with Unity Catalog by parameterizing the catalog and schema names, ensuring that development jobs read and write to development catalogs, completely isolated from production data.

Target Environment Definitions

A critical feature of DABs is the ability to define multiple targets . A target maps a logical environment (like dev , staging , or prod ) to a specific Databricks workspace and configuration set. In larger enterprise architectures, each target typically corresponds to an entirely separate Databricks workspace to ensure the blast radius of any misconfiguration is kept strictly to non-production environments.

Environment Isolation

Target Typical Use Case Configuration Characteristics

dev Local development and testing default: true , often uses personal user credentials, points to a dev workspace or specific user folder. Permissions are permissive.

staging Integration testing Pre-production validation, uses service principals, runs against isolated staging catalogs. Performance testing is often done here to validate cluster sizing.

prod Production workloads Strictly uses service principals, locked-down permissions, deployed exclusively via CI/CD, writes to production catalogs. Read-only access for developers.

By switching targets, data engineers can deploy the exact same codebase to different workspaces without modifying the underlying source files, eliminating the "it works on my machine" problem. When the bundle is deployed to the prod target, the Databricks CLI natively uses the prod configuration, including specific service principal credentials, avoiding accidental cross-contamination.

Declaring Resources

DABs support the declaration of various Databricks resources. The most common resources declared in a databricks.yml file are:

Jobs: Scheduled or triggered workflows consisting of multiple tasks (notebooks, Python wheels, SQL scripts). These definitions include cluster sizing, retry policies, and timeout constraints.

Pipelines: Delta Live Tables (DLT) pipelines, specifying the edition (core, pro, advanced) and the path to the pipeline source code, as well as target schemas.

Artifacts: Compiled code (like Python .whl files) that need to be built and uploaded to the workspace before execution.

Model Serving Endpoints: Definitions for serving MLflow models as REST APIs.

Example: Declaring a DLT Pipeline resources:

pipelines:

my_dlt_pipeline:

  • name: "${bundle.target}_dlt_pipeline"
  • development: true # Set to false in prod target

clusters:

  • label: "default"
  • num_workers: 1

libraries:

- notebook:

path: ./src/dlt_pipeline.sql

When declaring DLT pipelines, the development flag is crucial. In a dev target, setting this to true ensures that clusters are reused across pipeline updates, significantly accelerating the development cycle. In a prod target, this must be overridden to false so the pipeline runs in production mode, spinning up fresh, isolated clusters for execution and terminating them upon completion.

The Bundle Lifecycle Commands

The Databricks CLI provides a suite of commands to manage the bundle lifecycle. Understanding these commands and their order of operations is heavily tested on the professional exam.

1. databricks bundle validate

Before deploying, you must ensure your configuration is syntactically correct. The databricks bundle validate command parses the databricks.yml file, resolves variable substitutions, and checks for schema violations. Crucially, this command does not communicate with the Databricks workspace to create or modify resources. It is purely a local validation step, making it ideal for the early stages of a CI/CD pipeline. By running validation on every commit, teams can catch syntax errors long before they attempt to deploy broken configurations.

2. databricks bundle deploy

The databricks bundle deploy command synchronizes your local project state with the target Databricks workspace. Under the hood, this command performs several critical actions:

It builds any declared artifacts (e.g., compiling a Python wheel using standard setuptools or poetry ).

It uploads the local files (notebooks, SQL scripts, built artifacts) to the Databricks workspace (typically into the workspace files or DBFS depending on the configuration).

It calls the Databricks REST API to create or update the declared resources (Jobs, DLT pipelines) to match the state defined in the bundle.

It applies any tag or permission changes specified in the YAML configuration.

By default, if no target is specified via the -t flag, it deploys to the target marked with default: true .

3. databricks bundle run

Once a bundle is deployed, you can trigger its resources using databricks bundle run . This command requires you to specify the resource key you wish to execute. # Runs the daily_etl job in the default (dev) target

databricks bundle run daily_etl

  • # Runs the daily_etl job in the prod target
  • databricks bundle run daily_etl -t prod

This command submits a run request to the Databricks Jobs or DLT API and streams the output/logs back to your local terminal, allowing you to monitor execution without switching to the Databricks UI. It is highly beneficial for executing integration tests as part of a CD pipeline.

Practical Scenario: DRY Configurations and Overrides

Imagine you have a single data processing pipeline that needs to run in development with a small cluster and in production with a massive cluster. Instead of writing two separate JSON definitions, DABs allow you to handle this gracefully using variables and target overrides. variables:

worker_count:

default: 2

targets:

prod:

variables:

worker_count: 10

resources:

jobs:

scalable_job:

job_clusters:

- job_cluster_key: main

new_cluster:

num_workers: ${var.worker_count}

When deployed to dev , the job is provisioned with 2 workers. When deployed to prod , the override takes effect, and the job is provisioned with 10 workers. This variable injection is a powerful feature that ensures parity between environments while accommodating necessary scaling differences. Another common pattern is using bundle variables to swap out instance profiles or IAM roles depending on the environment, allowing a dev job to read from a sandbox S3 bucket while the prod job reads from the secured, production S3 bucket.