CertSafari
    Databricks Certified Data Engineer Associate· Lessons

    Domain 5 · Lesson 22/33

    Bundle Target Overrides: Promoting One Codebase from Dev to Prod

    Understand environment-specific configuration using Automation Bundle

    12 min read
    2.5% of exam
    4 sources
    Published 3 Oct 2026
    Docs as of 30 Sep 2026

    What you will be able to do

    • Define dev, staging and production targets in databricks.yml and select one with -t
    • Predict how target settings join with and override top-level resource settings by job_cluster_key, label and task_key
    • Configure per-target workspace host, root_path, deployment mode and run_as identity for promotion

    1.Targets: one configuration, several destinations

    A bundle has exactly one databricks.yml at its root. Its top-level mappings (resources, workspace, artifacts, variables) are the defaults for every environment. The targets mapping lists the environments you deploy to. Under each target you can override workspace, resources, artifacts, variables, run_as, permissions, mode, presets and more. Only one target can be marked default: true.

    The simplest promotion step is to point a prod target at a different workspace and a different cluster. Everything you don't override falls back to the top-level definition.

    A prod target that changes only the host and the task's clusteryaml
    targets:
      dev:
        default: true
      prod:
        workspace:
          host: https://<production-workspace-url>
        resources:
          jobs:
            hello-job:
              name: hello-job
              tasks:
                - task_key: hello-task
                  existing_cluster_id: 2345-678901-fabcd456

    The prod target does not repeat notebook_task. It inherits it from the top-level job. The docs' first example reads its credentials from a local profile named DEFAULT. Databricks recommends the host mapping instead of the default mapping wherever possible, because it makes your bundle configuration files more portable. That advice is about how credentials are found, not about default: true, which only chooses the target used when you pass no -t. The CLI matches the host to a profile in .databrickscfg. If several profiles match, you must pass --profile.

    You choose a target with -t (or --target) on validate, deploy and run. Commands without -t go to the default target.

    Deploying and running in prod when dev is the default targetbash
    # You must specify "-t prod", because the "dev" target
    # is already set to "default: true":
    databricks bundle validate
    databricks bundle deploy -t prod
    databricks bundle run -t prod hello_job

    A note on names: the docs' YAML declares the job under the key hello-job, but its run commands say hello_job. The sources do not explain the difference, so treat it as an inconsistency in the docs. In your own bundle, pass bundle run the resource key exactly as it is written in your YAML, as the run_as example does with databricks bundle run my_test_job_1.

    Checkpoint 1 of 5· Check yourself

    dev is marked default: true and prod overrides the cluster. A CI script runs databricks bundle deploy -t prod and then databricks bundle run hello_job, with no -t on the second command. Where does the run go?

    Checkpoint 2 of 5· Exam question

    How does an engineer declare a bundle variable in `databricks.yml` whose default value is a structured object, such as a cluster spec with a Spark version and worker count, rather than a single string?

    Sources1

    2.How target overrides merge with top-level settings

    A target override does not replace the whole resource. It is joined with the top-level definition, and where both set the same field, the target's value wins. For list entries such as job clusters, pipeline clusters and tasks, the bundle needs a key to know which entries to merge.

    Merge keys for target overrides
    What you overrideMatching keyWhere it lives
    Job cluster settingsjob_cluster_keyresources.jobs.<job>.job_clusters
    Lakeflow pipeline cluster settingslabel (default or maintenance)resources.pipelines.<pipeline>.clusters
    Job task settingstask_keyresources.jobs.<job>.tasks
    Artifact settingsartifact identifierartifacts.<artifact>
    Top-level and target job cluster settings joined by job_cluster_keyyaml
    resources:
      jobs:
        my-job:
          name: my-job
          job_clusters:
            - job_cluster_key: my-cluster
              new_cluster:
                spark_version: 13.3.x-scala2.12
    
    targets:
      development:
        resources:
          jobs:
            my-job:
              name: my-job
              job_clusters:
                - job_cluster_key: my-cluster
                  new_cluster:
                    node_type_id: i3.xlarge
                    num_workers: 1

    The validated result has all three fields. If the top level also set num_workers: 1 and the target set num_workers: 2, the result would be 2. Pipelines work the same way, matched on the cluster label. A top-level node_type_id plus a target num_workers on label default produces one cluster with both. Tasks only merge when task_key matches exactly. A target task with a different key is not joined to the top-level task.

    Checkpoint 3 of 5· Match them up

    Match each override to the key that joins it with the top-level definition

    Tap a term, then the definition that fits it.

    Checkpoint 4 of 5· Exam question

    A team wants every resource deployed by their bundle's `prod` target to run under a service principal instead of the deploying engineer's own identity. How should they configure this in `databricks.yml`?

    Sources2

    3.Modes and run identities across dev, staging and prod

    Targets also control how a deployment behaves, not just which values it uses. The mode mapping is optional. It applies a group of commonly used settings at once. mode: development is meant for pre-production iteration, and mode: production is meant for validated deliverables.

    Selected behaviours of the two deployment modes
    Behaviourmode: developmentmode: production
    Lakeflow pipelinesMarked development: trueValidates they are development: false
    Cluster overridesEnables --cluster-id on bundle deploy, overriding existing cluster definitionsDoes not allow overriding existing cluster definitions

    Development mode also does the following: - prepends the prefix [dev ${workspace.current_user.short_name}] to all resources that are not deployed as files or notebooks - tags each deployed job and pipeline with a dev Databricks tag - pauses all schedules and triggers - enables concurrent job runs - disables the deployment lock

    Production mode can also check that the current Git branch matches the branch set in the target. You can override that check with --force.

    Databricks recommends service principals for production deployments. If you do not use one, production mode adds two more validations. It checks that artifact_path, file_path, root_path and state_path are not overridden to a specific user. It also checks that run_as and permissions are specified, so it is clear which identities hold which permissions for deployments.

    To customise a mode, set presets on the target. Presets override the mode's defaults, and settings on individual resources override presets.

    The identity a job runs as is also set per target. Databricks calls it best practice to configure run identities for staging and production. Production should run as a service principal, which keeps the permission to run a workflow separate from the identity that deployed it.

    Staging and production targets with their own root_path and service principalyaml
      # Staging deployment settings
      staging:
        workspace:
          host: https://my-host.cloud.databricks.com
          root_path: /Shared/staging-workspace/.bundle/${bundle.name}/${bundle.target}
        run_as:
          service_principal_name: '69511ed2-zb27-444c-9863-4bc8ff497637'
    
      # Production deployment settings
      production:
        mode: production
        workspace:
          host: https://my-host.cloud.databricks.com
          root_path: /Shared/production-workspace/.bundle/${bundle.name}/${bundle.target}
        run_as:
          service_principal_name: '68ed9cd5-8923-4851-x0c1-c7536c67ff99'

    Checkpoint 5 of 5· Check yourself

    A production target has mode: production. An engineer tries to deploy it with a cluster override flag so the job runs on their personal cluster. What happens?

    Sources34

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.A target that sets only num_workers on a job cluster replaces the whole new_cluster block, so spark_version is lost.Why is that wrong?

      Target settings are joined with the top-level settings for the same job_cluster_key. Only fields defined in both places are overridden, and the target wins those.

      Covered in How target overrides merge with top-level settings

    2. 2.If a preset sets jobs_max_concurrent_runs to 20, every job uses 20, even a job whose own max_concurrent_runs is 10.Why is that wrong?

      Presets override the mode defaults, but a setting on an individual resource overrides the preset. That job keeps 10.

      Covered in Modes and run identities across dev, staging and prod

    Practise it for real

    Promote one hello-bundle from dev to prod by changing only variable values and target settings

    1. 1.In databricks.yml, declare a variable my_cluster_id with default 1234-567890-abcde123, use existing_cluster_id: ${var.my_cluster_id} in the hello-task, and run databricks bundle validate --output json.

      Why: Confirms the variable resolves before anything is deployed.

      You should see: The variables section shows my_cluster_id with default and value both 1234-567890-abcde123.

    2. 2.Add a prod target with workspace.host set to your production URL, and variables: my_cluster_id: 2345-678901-bcdef234 under it.

      Why: A value in the targets mapping is checked before the top-level default.

      You should see: Deploying to prod uses 2345-678901-bcdef234. Deploying to dev still uses the default.

    3. 3.Run databricks bundle deploy -t dev, then databricks bundle run -t dev hello-job. Here hello-job is the resource key under resources.jobs in your YAML.

      Why: dev is the default target, so -t is optional, but stating it makes the CI step explicit. bundle run takes the resource key exactly as written in your YAML.

      You should see: A job prefixed [dev <your short name>] if dev uses mode: development, running on the default cluster.

    4. 4.Run databricks bundle deploy -t prod, then databricks bundle run -t prod hello-job.

      Why: The same files are promoted, and only target-level values change.

      You should see: The job is deployed to the production workspace, using the prod cluster ID.

    Stuck? Get a nudge

    If prod picks up the wrong cluster, look for a BUNDLE_VAR_my_cluster_id environment variable. It takes priority over the target mapping.

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “Databricks recommends that you use the host mapping instead of the default mapping wherever possible”
      ↩︎ Targets: one configuration, several destinations
      “you do not need to declare the notebook_task mapping within the prod mapping”
      ↩︎ Targets: one configuration, several destinations
      “You must specify "-t prod", because the "dev" target”
      ↩︎ Checkpoint
    2. 2.
      “then the setting in the targets mapping takes precedence over the setting in the top-level resources mapping”
      ↩︎ How target overrides merge with top-level settings
      “the task mappings' task_key must be set to the same value”
      ↩︎ How target overrides merge with top-level settings
      “then the setting in the targets mapping takes precedence over the setting in the top-level resources mapping”
      ↩︎ Exam trap 1
      “spark_version in the top-level resources mapping is combined with node_type_id and num_workers in the resources mapping in targets”
      ↩︎ Prediction
      “use label within the cluster settings of a pipeline definition to identify cluster settings in a top-level resources mapping”
      ↩︎ Checkpoint
    3. 3.
      “Deployment modes are a convenience for applying a group of commonly used settings at once.”
      ↩︎ Modes and run identities across dev, staging and prod
      “Prepends all resources that are not deployed as files or notebooks with the prefix”
      ↩︎ Modes and run identities across dev, staging and prod
      “Validates that the run_as and permissions mappings are specified to clarify which identities have specific permissions for deployments.”
      ↩︎ Modes and run identities across dev, staging and prod
      “presets override the default mode behavior, and settings of individual resources override the presets”
      ↩︎ Exam trap 2
      “setting the mode mapping to production does not allow overriding any existing cluster definitions”
      ↩︎ Checkpoint
    4. 4.
      “It is best practice to configure run identities for staging and production target deployments.”
      ↩︎ Modes and run identities across dev, staging and prod
      “Decouples the permission to run the production workflow from the identity that created or deployed the bundle.”
      ↩︎ Modes and run identities across dev, staging and prod

    Spotted a mistake, or was something unclear? Tell us.