Skip to content

bundle: add per-resource deploy_targets to scope resources to targets (draft for #2878)#5967

Draft
ankit481 wants to merge 1 commit into
databricks:mainfrom
ankit481:bundle-per-resource-deploy-targets
Draft

bundle: add per-resource deploy_targets to scope resources to targets (draft for #2878)#5967
ankit481 wants to merge 1 commit into
databricks:mainfrom
ankit481:bundle-per-resource-deploy-targets

Conversation

@ankit481

@ankit481 ankit481 commented Jul 17, 2026

Copy link
Copy Markdown

Draft to support the design discussion on #2878. Context and the two options considered are in this comment.

Summary

This is a draft to make the design conversation on #2878 concrete. It adds an optional deploy_targets field to any bundle resource. When the field is set, the resource is deployed only to the targets whose names appear in the list, and it is dropped from the configuration for every other target. When the field is omitted, the resource is deployed to every target, which is the current behavior, so this change is additive and existing bundles are unaffected.

The request in #2878 is for a way to include configuration for one target and not others. The include section is global today, so the common workaround is to nest a resource under targets.<name>.resources, or to define the body once under a YAML anchor and alias it under each target in a per-file targets: block. That works, but the target membership ends up duplicated across files and is only visible by reading each file or running bundle validate per target. deploy_targets keeps the resource defined once at the top level and puts its target membership on the resource itself, which also covers the case where a single file defines several resources and a target needs only some of them.

I am opening this as a draft rather than proposing it for merge. It is one of two shapes discussed on the issue (the other is a per-target include list), and I thought it would be easier to look at the code alongside the discussion so the team can decide the direction and the field name. I am glad to rework it toward the other option, adjust the naming, or set it aside, depending on what you prefer.

Example

resources:
  jobs:
    shared_job:
      name: shared_job
      # no deploy_targets: deployed to every target

    dev_and_staging_job:
      name: dev_and_staging_job
      deploy_targets: [dev, staging]

    prod_only_job:
      name: prod_only_job
      deploy_targets: [prod]

With this config, bundle validate -t dev resolves shared_job and dev_and_staging_job, -t staging resolves the same two, and -t prod resolves shared_job and prod_only_job.

Implementation

  • deploy_targets is added once to BaseResource (bundle/config/resources/base.go), so it applies to every resource type through the embedded struct. ExternalLocation copies the base fields by hand rather than embedding, so the field and accessor are added there too.
  • A FilterDeployTargets mutator (bundle/config/mutator/resourcemutator/filter_deploy_targets.go) drops resources whose deploy_targets list is set and does not contain the selected target. It runs in the initialize phase after resources are materialized and after PythonMutator, so dynamically added resources are also filtered, and before validation, so required-field checks only see resources that will be deployed.
  • The field is bundle-only and does not reach the deployment engine. Terraform generation projects each resource onto the typed schema through convert.Normalize, which drops the field the same way it drops id, url, and lifecycle. For the direct engine it is registered in the config-only field list, alongside lifecycle, grants, and permissions.
  • The JSON schema and the generated maps are regenerated.

Tests

  • Unit tests for the mutator covering: a resource with no list is kept everywhere; a resource is kept only in its listed targets; a target that appears in no list keeps only the unrestricted resources; filtering applies across resource types (jobs and pipelines).
  • An acceptance test (acceptance/bundle/deploy_targets) that runs bundle validate for three targets and checks the resolved resource set for each, under both the terraform and direct engines.

Open questions

  • Direction: this per-resource shape, a per-target include list, or both. They cover different cases and are discussed on [Feature Request] DABs: allow target specific includes #2878.
  • Field name: deploy_targets is a placeholder if you prefer something else.
  • Whether a resource listing a target that does not exist should warn.

Related: #2878.

Adds an optional deploy_targets list to any bundle resource. When set, the
resource is deployed only to the targets whose names appear in the list and
is dropped from the configuration for every other target. When omitted, the
resource is deployed to every target, so the change is additive and existing
bundles are unaffected.

This addresses the request in databricks#2878 for scoping configuration to a subset of
targets without nesting the resource body under targets.<name>.resources or
duplicating a per-file target matrix. The field is defined once on BaseResource
so it applies to every resource type, filtered by a FilterDeployTargets mutator
that runs after resources are materialized and before validation, and kept out
of the deployment engine the same way lifecycle is.

Includes unit tests for the mutator and an acceptance test across the terraform
and direct engines.
@github-actions

Copy link
Copy Markdown
Contributor

An authorized user can trigger integration tests manually by following the instructions below:

Trigger:
go/deco-tests-run/cli

Inputs:

  • PR number: 5967
  • Commit SHA: 6df7adb6f3693bcd3878847cb501faa9879f0f1e

Checks will be approved automatically on success.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant