From d6775f0bf85ba0ee9348bd54f562055226a280e8 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Tue, 10 Feb 2026 16:55:36 +0100 Subject: [PATCH 01/21] Add backend_defaults support to resource lifecycle config Adds a new `backend_defaults` rule type that skips changes where old/new are nil but remote is set, constrained to specific field patterns and optionally to specific allowed values. Values use json.RawMessage to support type-accurate comparison against the remote state. Co-Authored-By: Claude Opus 4.6 --- bundle/deployplan/plan.go | 1 + bundle/direct/bundle_plan.go | 44 ++++++++++++++++++++++++++ bundle/direct/dresources/all_test.go | 3 ++ bundle/direct/dresources/config.go | 35 ++++++++++++++++++++ bundle/direct/dresources/resources.yml | 2 ++ 5 files changed, 85 insertions(+) diff --git a/bundle/deployplan/plan.go b/bundle/deployplan/plan.go index 7098e63383..e739d4497c 100644 --- a/bundle/deployplan/plan.go +++ b/bundle/deployplan/plan.go @@ -99,6 +99,7 @@ type ChangeDesc struct { // Possible values for Reason field const ( ReasonServerSideDefault = "server_side_default" + ReasonBackendDefault = "backend_default" ReasonAlias = "alias" ReasonRemoteAlreadySet = "remote_already_set" ReasonEmpty = "empty" diff --git a/bundle/direct/bundle_plan.go b/bundle/direct/bundle_plan.go index 23cb3cd3ff..a693397402 100644 --- a/bundle/direct/bundle_plan.go +++ b/bundle/direct/bundle_plan.go @@ -2,6 +2,7 @@ package direct import ( "context" + "encoding/json" "errors" "fmt" "maps" @@ -382,6 +383,12 @@ func addPerFieldActions(ctx context.Context, adapter *dresources.Adapter, change } else if reason, ok := shouldSkip(generatedCfg, path, ch); ok { ch.Action = deployplan.Skip ch.Reason = reason + } else if reason, ok := shouldSkipBackendDefault(cfg, path, ch); ok { + ch.Action = deployplan.Skip + ch.Reason = reason + } else if reason, ok := shouldSkipBackendDefault(generatedCfg, path, ch); ok { + ch.Action = deployplan.Skip + ch.Reason = reason } else if ch.New == nil && ch.Old == nil && ch.Remote != nil && path.IsDotString() { // The field was not set by us, but comes from the remote state. // This could either be server-side default or a policy. @@ -461,6 +468,43 @@ func shouldUpdateOrRecreate(cfg *dresources.ResourceLifecycleConfig, path *struc return deployplan.Undefined, "" } +// shouldSkipBackendDefault checks if a change should be skipped because the remote value +// is a known backend default. Applies when old and new are nil but remote is set. +// If the rule has allowed values, the remote value must match one of them. +func shouldSkipBackendDefault(cfg *dresources.ResourceLifecycleConfig, path *structpath.PathNode, ch *deployplan.ChangeDesc) (string, bool) { + if cfg == nil || ch.Old != nil || ch.New != nil || ch.Remote == nil { + return "", false + } + for _, rule := range cfg.BackendDefaults { + if !path.HasPatternPrefix(rule.Field) { + continue + } + if len(rule.Values) == 0 { + return deployplan.ReasonBackendDefault, true + } + if matchesAllowedValue(ch.Remote, rule.Values) { + return deployplan.ReasonBackendDefault, true + } + } + return "", false +} + +// matchesAllowedValue checks if the remote value matches one of the allowed JSON values. +// Each json.RawMessage is unmarshaled into the same type as remote for comparison. +func matchesAllowedValue(remote any, values []json.RawMessage) bool { + remoteType := reflect.TypeOf(remote) + for _, raw := range values { + candidate := reflect.New(remoteType).Interface() + if err := json.Unmarshal(raw, candidate); err != nil { + continue + } + if structdiff.IsEqual(remote, reflect.ValueOf(candidate).Elem().Interface()) { + return true + } + } + return false +} + func allEmpty(values ...any) bool { for _, v := range values { if v == nil { diff --git a/bundle/direct/dresources/all_test.go b/bundle/direct/dresources/all_test.go index 8210b1ed32..559685b891 100644 --- a/bundle/direct/dresources/all_test.go +++ b/bundle/direct/dresources/all_test.go @@ -870,6 +870,9 @@ func validateResourceConfig(t *testing.T, stateType reflect.Type, cfg *ResourceL for _, p := range cfg.IgnoreRemoteChanges { assert.NoError(t, structaccess.ValidatePattern(stateType, p.Field), "IgnoreRemoteChanges: %s", p.Field) } + for _, p := range cfg.BackendDefaults { + assert.NoError(t, structaccess.ValidatePattern(stateType, p.Field), "BackendDefaults: %s", p.Field) + } } func setupTestServerClient(t *testing.T) (*testserver.Server, *databricks.WorkspaceClient) { diff --git a/bundle/direct/dresources/config.go b/bundle/direct/dresources/config.go index eba9e62f5a..598eaf3f2c 100644 --- a/bundle/direct/dresources/config.go +++ b/bundle/direct/dresources/config.go @@ -2,6 +2,7 @@ package dresources import ( _ "embed" + "encoding/json" "sync" "github.com/databricks/cli/libs/structs/structpath" @@ -14,6 +15,36 @@ type FieldRule struct { Reason string `yaml:"reason"` } +// BackendDefaultRule represents a field that may be set by the backend as a default. +// When old and new are nil but remote is set, and the field matches, the change is skipped. +// If Values is non-empty, the remote value must match one of the allowed values. +type BackendDefaultRule struct { + Field *structpath.PatternNode `yaml:"field"` + Values []json.RawMessage `yaml:"values,omitempty"` +} + +// UnmarshalYAML implements custom YAML unmarshaling for BackendDefaultRule. +// Values are parsed from native YAML types and stored as JSON bytes. +func (b *BackendDefaultRule) UnmarshalYAML(unmarshal func(any) error) error { + type helper struct { + Field *structpath.PatternNode `yaml:"field"` + Values []any `yaml:"values,omitempty"` + } + var h helper + if err := unmarshal(&h); err != nil { + return err + } + b.Field = h.Field + for _, v := range h.Values { + raw, err := json.Marshal(v) + if err != nil { + return err + } + b.Values = append(b.Values, json.RawMessage(raw)) + } + return nil +} + // ResourceLifecycleConfig defines lifecycle behavior for a resource type. type ResourceLifecycleConfig struct { // IgnoreRemoteChanges: field patterns where remote changes are ignored (output-only, policy-set). @@ -27,6 +58,10 @@ type ResourceLifecycleConfig struct { // UpdateIDOnChanges: field patterns that trigger UpdateWithID when changed. UpdateIDOnChanges []FieldRule `yaml:"update_id_on_changes,omitempty"` + + // BackendDefaults: fields where the backend may set defaults. + // When old and new are nil but remote is set, and the remote value matches allowed values (if specified), the change is skipped. + BackendDefaults []BackendDefaultRule `yaml:"backend_defaults,omitempty"` } // Config is the root configuration structure for resource lifecycle behavior. diff --git a/bundle/direct/dresources/resources.yml b/bundle/direct/dresources/resources.yml index 08db4c47bf..9ee2893601 100644 --- a/bundle/direct/dresources/resources.yml +++ b/bundle/direct/dresources/resources.yml @@ -6,6 +6,8 @@ # update_id_on_changes: fields that trigger UpdateWithID (ID may change) # ignore_remote_changes: fields where remote changes are ignored # ignore_local_changes: fields where local changes are ignored (can't be updated via API) +# backend_defaults: fields where the backend may set defaults (skipped when old/new are nil but remote is set) +# Optional "values" list constrains which remote values are allowed (as JSON-compatible literals). # # Each field entry has: # field: the field path From e26e11b58ab8d8b57bdf9e72c2409b3226da2f37 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Tue, 10 Feb 2026 17:14:18 +0100 Subject: [PATCH 02/21] Add backend_defaults entries for jobs, pipelines, clusters, sql_warehouses Each entry references the corresponding Terraform provider default with a link to the source and the exact line that sets the default. Co-Authored-By: Claude Opus 4.6 --- bundle/direct/dresources/resources.yml | 80 +++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/bundle/direct/dresources/resources.yml b/bundle/direct/dresources/resources.yml index 9ee2893601..e316c259b2 100644 --- a/bundle/direct/dresources/resources.yml +++ b/bundle/direct/dresources/resources.yml @@ -32,12 +32,47 @@ resources: - field: job_clusters[*].new_cluster.gcp_attributes reason: managed - # can also be added to backend_defaults with value=false once we have that - field: tasks[*].new_cluster.enable_elastic_disk reason: managed - field: job_clusters[*].new_cluster.enable_elastic_disk reason: managed + backend_defaults: + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L570 + # s.SchemaPath("max_concurrent_runs").SetDefault(1) + - field: max_concurrent_runs + values: [1] + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L531 + # s.SchemaPath("format").SetComputed() + - field: format + values: ["MULTI_TASK", "SINGLE_TASK"] + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L534 + # s.SchemaPath("schedule", "pause_status").SetDefault("UNPAUSED") + - field: schedule.pause_status + values: ["UNPAUSED"] + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L535 + # s.SchemaPath("trigger", "pause_status").SetDefault("UNPAUSED") + - field: trigger.pause_status + values: ["UNPAUSED"] + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L536 + # s.SchemaPath("continuous", "pause_status").SetDefault("UNPAUSED") + - field: continuous.pause_status + values: ["UNPAUSED"] + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L639 + # s.SchemaPath("task", "run_if").SetSuppressDiffWithDefault(jobs.RunIfAllSuccess) + - field: "tasks[*].run_if" + values: ["ALL_SUCCESS"] + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L640 + # s.SchemaPath("task", "for_each_task", "task", "run_if").SetSuppressDiffWithDefault(jobs.RunIfAllSuccess) + - field: "tasks[*].for_each_task.task.run_if" + values: ["ALL_SUCCESS"] + pipelines: recreate_on_changes: - field: storage @@ -70,6 +105,16 @@ resources: # "id" is output-only, providing it in config would be a mistake - field: id reason: "!drop" + backend_defaults: + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/pipelines/resource_pipeline.go#L254 + # s.SchemaPath("edition").SetDefault("ADVANCED") + - field: edition + values: ["ADVANCED"] + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/pipelines/resource_pipeline.go#L255 + # s.SchemaPath("channel").SetDefault("CURRENT") + - field: channel + values: ["CURRENT"] models: recreate_on_changes: @@ -236,6 +281,39 @@ resources: - field: scope_name reason: id_changes + clusters: + backend_defaults: + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L320-L324 + # s.AddNewField("autotermination_minutes", &schema.Schema{Default: 60}) + - field: autotermination_minutes + values: [60] + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L109-L118 + # DataSecurityModeDiffSuppressFunc: suppress when old != "" && new == "" + - field: data_security_mode + + sql_warehouses: + backend_defaults: + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L61 + # common.SetDefault(m["auto_stop_mins"], 120) + - field: auto_stop_mins + values: [120] + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L68 + # common.SetDefault(m["enable_photon"], true) + - field: enable_photon + values: [true] + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L72 + # common.SetDefault(m["max_num_clusters"], 1) + - field: max_num_clusters + values: [1] + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L80 + # common.SetDefault(m["spot_instance_policy"], "COST_OPTIMIZED") + - field: spot_instance_policy + values: ["COST_OPTIMIZED"] + postgres_projects: recreate_on_changes: # project_id is immutable (part of hierarchical name, not in API spec) From 31a53c4196c447735f7411439231d5e8d8e3c3f7 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Tue, 10 Feb 2026 17:36:24 +0100 Subject: [PATCH 03/21] Add ignore_remote_changes and backend_defaults for remaining resources Based on analysis of Terraform provider (commit 4eba541): - clusters: ignore aws/azure/gcp_attributes (SetSuppressDiff), enable_elastic_disk (SetComputed) - sql_warehouses: ignore channel, tags, warehouse_type (SetSuppressDiff) - model_serving_endpoints: ignore config.traffic_config (SetComputed + SuppressDiff on routes); backend_defaults for served_entities name/ workload_type and auto_capture_config.enabled (SetComputed) - dashboards: backend_defaults for embed_credentials=true (SetDefault) - apps: backend_defaults for compute_size (SetComputed) Co-Authored-By: Claude Opus 4.6 --- bundle/direct/dresources/resources.yml | 60 ++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/bundle/direct/dresources/resources.yml b/bundle/direct/dresources/resources.yml index e316c259b2..9a6970dafd 100644 --- a/bundle/direct/dresources/resources.yml +++ b/bundle/direct/dresources/resources.yml @@ -165,6 +165,24 @@ resources: reason: immutable - field: route_optimized reason: immutable + ignore_remote_changes: + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/serving/resource_model_serving.go#L370 + # common.CustomizeSchemaPath(m, "config", "traffic_config").SetComputed() + # Routes have custom SuppressDiff (lines 387-388) + - field: config.traffic_config + reason: "managed" + backend_defaults: + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/serving/resource_model_serving.go#L383 + # common.CustomizeSchemaPath(m, "config", "served_entities", "name").SetComputed() + - field: "config.served_entities[*].name" + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/serving/resource_model_serving.go#L384 + # common.CustomizeSchemaPath(m, "config", "served_entities", "workload_type").SetComputed() + - field: "config.served_entities[*].workload_type" + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/serving/resource_model_serving.go#L372 + # common.CustomizeSchemaPath(m, "config", "auto_capture_config", "enabled").SetComputed() + - field: config.auto_capture_config.enabled registered_models: recreate_on_changes: @@ -243,6 +261,11 @@ resources: reason: id_changes dashboards: + backend_defaults: + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/dashboards/resource_dashboard.go#L69 + # s.SchemaPath("embed_credentials").SetDefault(true) + - field: embed_credentials + values: [true] ignore_remote_changes: # "serialized_dashboard" locally and remotely will have different contents @@ -261,6 +284,10 @@ resources: recreate_on_changes: - field: name reason: immutable + backend_defaults: + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/internal/providers/pluginfw/products/app/resource_app.go#L41 + # s["compute_size"] = s["compute_size"].SetComputed() + - field: compute_size secret_scopes: recreate_on_changes: @@ -282,6 +309,23 @@ resources: reason: id_changes clusters: + ignore_remote_changes: + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L361-L363 + # s.SchemaPath("aws_attributes").SetSuppressDiff() + # s.SchemaPath("azure_attributes").SetSuppressDiff() + # s.SchemaPath("gcp_attributes").SetSuppressDiff() + - field: aws_attributes + reason: "managed" + - field: azure_attributes + reason: "managed" + - field: gcp_attributes + reason: "managed" + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L331 + # s.SchemaPath("enable_elastic_disk").SetComputed() + - field: enable_elastic_disk + reason: "managed" + backend_defaults: # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L320-L324 # s.AddNewField("autotermination_minutes", &schema.Schema{Default: 60}) @@ -293,6 +337,22 @@ resources: - field: data_security_mode sql_warehouses: + ignore_remote_changes: + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L62 + # common.CustomizeSchemaPath(m, "channel").SetSuppressDiff() + - field: channel + reason: "managed" + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L82 + # common.CustomizeSchemaPath(m, "tags").SetSuppressDiff() + - field: tags + reason: "managed" + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L85-L87 + # common.CustomizeSchemaPath(m, "warehouse_type").SetSuppressDiff() + - field: warehouse_type + reason: "managed" + backend_defaults: # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L61 # common.SetDefault(m["auto_stop_mins"], 120) From b123ac0082fe7c7f17052a5bdfab1b440b1fd3d2 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Tue, 10 Feb 2026 18:11:02 +0100 Subject: [PATCH 04/21] Fix exhaustruct lint: add BackendDefaults to empty config Co-Authored-By: Claude Opus 4.6 --- bundle/direct/dresources/config.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bundle/direct/dresources/config.go b/bundle/direct/dresources/config.go index 598eaf3f2c..0b71f51382 100644 --- a/bundle/direct/dresources/config.go +++ b/bundle/direct/dresources/config.go @@ -20,7 +20,7 @@ type FieldRule struct { // If Values is non-empty, the remote value must match one of the allowed values. type BackendDefaultRule struct { Field *structpath.PatternNode `yaml:"field"` - Values []json.RawMessage `yaml:"values,omitempty"` + Values []json.RawMessage `yaml:"values,omitempty"` } // UnmarshalYAML implements custom YAML unmarshaling for BackendDefaultRule. @@ -85,6 +85,7 @@ var ( IgnoreLocalChanges: nil, RecreateOnChanges: nil, UpdateIDOnChanges: nil, + BackendDefaults: nil, } ) From cfaf9b28a52080747714a1de2fbd880f82aa2573 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Tue, 10 Feb 2026 21:12:09 +0100 Subject: [PATCH 05/21] Remove server_side_default catch-all; replace with explicit backend_defaults The generic catch-all rule that marked all remote-only fields as server_side_default is replaced with explicit backend_defaults entries for each resource type. This makes field handling explicit and auditable. New backend_defaults entries: - jobs: timeout_seconds, tasks[*].timeout_seconds, tasks[*].notebook_task.source, tasks[*].new_cluster.data_security_mode, job_clusters[*].new_cluster.data_security_mode - pipelines: storage, root_path - model_serving_endpoints: route_optimized - registered_models: storage_location, owner, full_name, metastore_id (plus ignore_remote_changes for created_at/by, updated_at/by) - volumes: storage_location Also removes the server_side_default special case in configsync/diff.go (per existing TODO) and the ReasonServerSideDefault constant. Co-Authored-By: Claude Opus 4.6 --- .../interactive_cluster/output.txt | 2 +- .../remote_pipeline/out.plan_skip.direct.json | 8 +-- .../deploy/data_security_mode/output.txt | 4 +- .../grants/volumes/out.plan2.direct.json | 2 +- .../update/out.plan_delete_all.direct.json | 2 +- .../update/out.plan_delete_one.direct.json | 2 +- .../update/out.plan_restore.direct.json | 2 +- .../update/out.plan_update.direct.json | 2 +- .../out.plan_recreate.direct.json | 2 +- .../volumes/change-name/out.plan.direct.json | 2 +- bundle/configsync/diff.go | 4 +- bundle/deployplan/plan.go | 9 ++-- bundle/direct/bundle_plan.go | 7 --- bundle/direct/dresources/resources.yml | 52 +++++++++++++++++++ cmd/bundle/deployment/migrate.go | 2 +- 15 files changed, 73 insertions(+), 29 deletions(-) diff --git a/acceptance/bundle/integration_whl/interactive_cluster/output.txt b/acceptance/bundle/integration_whl/interactive_cluster/output.txt index 57beb13d02..8ebcc456ad 100644 --- a/acceptance/bundle/integration_whl/interactive_cluster/output.txt +++ b/acceptance/bundle/integration_whl/interactive_cluster/output.txt @@ -61,7 +61,7 @@ Run URL: [DATABRICKS_URL]/?o=[NUMID]#job/[SOME_OTHER_JOB_ID]/run/[NUMID] [TIMESTAMP] "[default] Test Wheel Job [UNIQUE_NAME]" RUNNING [TIMESTAMP] "[default] Test Wheel Job [UNIQUE_NAME]" TERMINATED SUCCESS -Hello from my func +UPDATED MY FUNC Got arguments: ['my_test_code', 'one', 'two'] diff --git a/acceptance/bundle/resource_deps/remote_pipeline/out.plan_skip.direct.json b/acceptance/bundle/resource_deps/remote_pipeline/out.plan_skip.direct.json index 18585bffb5..3328c1be7c 100644 --- a/acceptance/bundle/resource_deps/remote_pipeline/out.plan_skip.direct.json +++ b/acceptance/bundle/resource_deps/remote_pipeline/out.plan_skip.direct.json @@ -25,7 +25,7 @@ "changes": { "storage": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "dbfs:/pipelines/[UUID]" } } @@ -57,7 +57,7 @@ "changes": { "storage": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "dbfs:/pipelines/[UUID]" } } @@ -89,7 +89,7 @@ "changes": { "storage": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "dbfs:/pipelines/[UUID]" } } @@ -121,7 +121,7 @@ "changes": { "storage": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "dbfs:/pipelines/[UUID]" } } diff --git a/acceptance/bundle/resources/clusters/deploy/data_security_mode/output.txt b/acceptance/bundle/resources/clusters/deploy/data_security_mode/output.txt index 9a6773a754..0a99281581 100644 --- a/acceptance/bundle/resources/clusters/deploy/data_security_mode/output.txt +++ b/acceptance/bundle/resources/clusters/deploy/data_security_mode/output.txt @@ -6,7 +6,9 @@ Updating deployment state... Deployment complete! >>> [CLI] bundle plan -Plan: 0 to add, 0 to change, 0 to delete, 1 unchanged +update clusters.test_cluster + +Plan: 0 to add, 1 to change, 0 to delete, 0 unchanged >>> [CLI] bundle deploy Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/[UNIQUE_NAME]/files... diff --git a/acceptance/bundle/resources/grants/volumes/out.plan2.direct.json b/acceptance/bundle/resources/grants/volumes/out.plan2.direct.json index b8f0621ae9..a6709a074f 100644 --- a/acceptance/bundle/resources/grants/volumes/out.plan2.direct.json +++ b/acceptance/bundle/resources/grants/volumes/out.plan2.direct.json @@ -39,7 +39,7 @@ "changes": { "storage_location": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "s3://deco-uc-prod-isolated-aws-us-east-1/metastore/[UUID]/volumes/[UUID]" } } diff --git a/acceptance/bundle/resources/permissions/pipelines/update/out.plan_delete_all.direct.json b/acceptance/bundle/resources/permissions/pipelines/update/out.plan_delete_all.direct.json index a8a906dcc4..af3718c59f 100644 --- a/acceptance/bundle/resources/permissions/pipelines/update/out.plan_delete_all.direct.json +++ b/acceptance/bundle/resources/permissions/pipelines/update/out.plan_delete_all.direct.json @@ -25,7 +25,7 @@ "changes": { "storage": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "dbfs:/pipelines/[FOO_ID]" } } diff --git a/acceptance/bundle/resources/permissions/pipelines/update/out.plan_delete_one.direct.json b/acceptance/bundle/resources/permissions/pipelines/update/out.plan_delete_one.direct.json index f9bd45988f..f11c8a77fc 100644 --- a/acceptance/bundle/resources/permissions/pipelines/update/out.plan_delete_one.direct.json +++ b/acceptance/bundle/resources/permissions/pipelines/update/out.plan_delete_one.direct.json @@ -25,7 +25,7 @@ "changes": { "storage": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "dbfs:/pipelines/[FOO_ID]" } } diff --git a/acceptance/bundle/resources/permissions/pipelines/update/out.plan_restore.direct.json b/acceptance/bundle/resources/permissions/pipelines/update/out.plan_restore.direct.json index 4827d439b0..fad11f3014 100644 --- a/acceptance/bundle/resources/permissions/pipelines/update/out.plan_restore.direct.json +++ b/acceptance/bundle/resources/permissions/pipelines/update/out.plan_restore.direct.json @@ -25,7 +25,7 @@ "changes": { "storage": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "dbfs:/pipelines/[FOO_ID]" } } diff --git a/acceptance/bundle/resources/permissions/pipelines/update/out.plan_update.direct.json b/acceptance/bundle/resources/permissions/pipelines/update/out.plan_update.direct.json index 34c36a5032..6fd7896b3d 100644 --- a/acceptance/bundle/resources/permissions/pipelines/update/out.plan_update.direct.json +++ b/acceptance/bundle/resources/permissions/pipelines/update/out.plan_update.direct.json @@ -25,7 +25,7 @@ "changes": { "storage": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "dbfs:/pipelines/[FOO_ID]" } } diff --git a/acceptance/bundle/resources/pipelines/recreate-keys/change-ingestion-definition/out.plan_recreate.direct.json b/acceptance/bundle/resources/pipelines/recreate-keys/change-ingestion-definition/out.plan_recreate.direct.json index 7a86cca523..021901f34e 100644 --- a/acceptance/bundle/resources/pipelines/recreate-keys/change-ingestion-definition/out.plan_recreate.direct.json +++ b/acceptance/bundle/resources/pipelines/recreate-keys/change-ingestion-definition/out.plan_recreate.direct.json @@ -69,7 +69,7 @@ }, "storage": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "dbfs:/pipelines/[MY_ID]" } } diff --git a/acceptance/bundle/resources/volumes/change-name/out.plan.direct.json b/acceptance/bundle/resources/volumes/change-name/out.plan.direct.json index dec07013ea..f6bfbfbc03 100644 --- a/acceptance/bundle/resources/volumes/change-name/out.plan.direct.json +++ b/acceptance/bundle/resources/volumes/change-name/out.plan.direct.json @@ -39,7 +39,7 @@ }, "storage_location": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "s3://deco-uc-prod-isolated-aws-us-east-1/metastore/[UUID]/volumes/[UUID]" } } diff --git a/bundle/configsync/diff.go b/bundle/configsync/diff.go index 481c5a4a93..0d8bddc2e9 100644 --- a/bundle/configsync/diff.go +++ b/bundle/configsync/diff.go @@ -145,9 +145,7 @@ func DetectChanges(ctx context.Context, b *bundle.Bundle, engine engine.EngineTy if entry.Changes != nil { for path, changeDesc := range entry.Changes { - // TODO: as for now in bundle plan all remote-side changes are considered as server-side defaults. - // Once it is solved - stop skipping server-side defaults in these checks and remove hardcoded default. - if changeDesc.Action == deployplan.Skip && changeDesc.Reason != deployplan.ReasonServerSideDefault { + if changeDesc.Action == deployplan.Skip { continue } diff --git a/bundle/deployplan/plan.go b/bundle/deployplan/plan.go index e739d4497c..48b3285f4c 100644 --- a/bundle/deployplan/plan.go +++ b/bundle/deployplan/plan.go @@ -98,12 +98,11 @@ type ChangeDesc struct { // Possible values for Reason field const ( - ReasonServerSideDefault = "server_side_default" - ReasonBackendDefault = "backend_default" - ReasonAlias = "alias" - ReasonRemoteAlreadySet = "remote_already_set" + ReasonBackendDefault = "backend_default" + ReasonAlias = "alias" + ReasonRemoteAlreadySet = "remote_already_set" ReasonEmpty = "empty" - ReasonCustom = "custom" + ReasonCustom = "custom" // Special reason that results in removing this change from the plan ReasonDrop = "!drop" diff --git a/bundle/direct/bundle_plan.go b/bundle/direct/bundle_plan.go index a693397402..5c518adcc9 100644 --- a/bundle/direct/bundle_plan.go +++ b/bundle/direct/bundle_plan.go @@ -389,13 +389,6 @@ func addPerFieldActions(ctx context.Context, adapter *dresources.Adapter, change } else if reason, ok := shouldSkipBackendDefault(generatedCfg, path, ch); ok { ch.Action = deployplan.Skip ch.Reason = reason - } else if ch.New == nil && ch.Old == nil && ch.Remote != nil && path.IsDotString() { - // The field was not set by us, but comes from the remote state. - // This could either be server-side default or a policy. - // In any case, this is not a change we should react to. - // Note, we only consider struct fields here. Adding/removing elements to/from maps and slices should trigger updates. - ch.Action = deployplan.Skip - ch.Reason = deployplan.ReasonServerSideDefault } else if action, reason := shouldUpdateOrRecreate(cfg, path); action != deployplan.Undefined { ch.Action = action ch.Reason = reason diff --git a/bundle/direct/dresources/resources.yml b/bundle/direct/dresources/resources.yml index 9a6970dafd..37acb58715 100644 --- a/bundle/direct/dresources/resources.yml +++ b/bundle/direct/dresources/resources.yml @@ -73,6 +73,23 @@ resources: - field: "tasks[*].for_each_task.task.run_if" values: ["ALL_SUCCESS"] + # timeout_seconds has implicit default of 0 (Go zero value) + - field: timeout_seconds + values: [0] + - field: "tasks[*].timeout_seconds" + values: [0] + - field: "tasks[*].for_each_task.task.timeout_seconds" + values: [0] + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L521 + # s.SchemaPath("task", "notebook_task", "source").SetSuppressDiff() + - field: "tasks[*].notebook_task.source" + - field: "tasks[*].for_each_task.task.notebook_task.source" + + # Same as clusters.data_security_mode: backend sets this when not specified + - field: "tasks[*].new_cluster.data_security_mode" + - field: "job_clusters[*].new_cluster.data_security_mode" + pipelines: recreate_on_changes: - field: storage @@ -116,6 +133,14 @@ resources: - field: channel values: ["CURRENT"] + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/pipelines/resource_pipeline.go#L238 + # s.SchemaPath("storage").SetCustomSuppressDiff(suppressStorageDiff) + # Backend generates storage path like dbfs:/pipelines/ when not set by user. + - field: storage + + # root_path is computed by the backend when not set by user. + - field: root_path + models: recreate_on_changes: # Recreate matches current behavior of Terraform. It is possible to rename without recreate @@ -184,7 +209,23 @@ resources: # common.CustomizeSchemaPath(m, "config", "auto_capture_config", "enabled").SetComputed() - field: config.auto_capture_config.enabled + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/serving/resource_model_serving.go#L395-L396 + # route_optimized is ForceNew; backend returns false when not set by user. + - field: route_optimized + values: [false] + registered_models: + ignore_remote_changes: + # Output-only timestamp/user fields zeroed in RemapState but still show up + # via ForceSendFields. These should never participate in diffs. + - field: created_at + reason: output_only + - field: created_by + reason: output_only + - field: updated_at + reason: output_only + - field: updated_by + reason: output_only recreate_on_changes: # The name can technically be updated without recreate. We recreate for now though # to match TF implementation. @@ -196,6 +237,14 @@ resources: reason: immutable - field: storage_location reason: immutable + backend_defaults: + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/catalog/resource_registered_model.go#L28 + # m["storage_location"].Computed = true + - field: storage_location + # owner, full_name, metastore_id are Computed in TF (backend-set output fields). + - field: owner + - field: full_name + - field: metastore_id quality_monitors: recreate_on_changes: @@ -259,6 +308,9 @@ resources: update_id_on_changes: - field: name reason: id_changes + backend_defaults: + # storage_location is Computed; backend generates it for managed volumes. + - field: storage_location dashboards: backend_defaults: diff --git a/cmd/bundle/deployment/migrate.go b/cmd/bundle/deployment/migrate.go index 6f67f8ce43..6c6e9951ba 100644 --- a/cmd/bundle/deployment/migrate.go +++ b/cmd/bundle/deployment/migrate.go @@ -245,7 +245,7 @@ To start using direct engine, deploy with DATABRICKS_BUNDLE_ENGINE=direct env va // For most resources state consists of fully resolved local config snapshot + id. // Dashboards are special in that they also store "etag" in state which is not provided by user but // comes from remote state. If we don't store "etag" in state, we won't detect remote drift, because - // local=nil, remote="" which will be classified as "server_side_default". + // local=nil, remote="" which will be classified as a backend default and skipped. for key := range plan.Plan { etag := etags[key] From dbaec26d10c63b3bcb91c4556ce6a4b5d279f51a Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 11 Feb 2026 12:05:18 +0100 Subject: [PATCH 06/21] update interactive_single_user test --- .../integration_whl/interactive_single_user/out.direct.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acceptance/bundle/integration_whl/interactive_single_user/out.direct.txt b/acceptance/bundle/integration_whl/interactive_single_user/out.direct.txt index 2c32ebd11d..c9ac86bb07 100644 --- a/acceptance/bundle/integration_whl/interactive_single_user/out.direct.txt +++ b/acceptance/bundle/integration_whl/interactive_single_user/out.direct.txt @@ -1,6 +1,6 @@ Hello from my func Got arguments: ['my_test_code', 'one', 'two'] -Hello from my func +UPDATED MY FUNC Got arguments: ['my_test_code', 'one', 'two'] From 5b53803148721871fa23476f9be809b26dac8e3f Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 11 Feb 2026 13:06:20 +0100 Subject: [PATCH 07/21] formatting --- bundle/direct/dresources/resources.yml | 35 ++++++++++++++------------ 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/bundle/direct/dresources/resources.yml b/bundle/direct/dresources/resources.yml index 37acb58715..7fcd58f436 100644 --- a/bundle/direct/dresources/resources.yml +++ b/bundle/direct/dresources/resources.yml @@ -76,19 +76,19 @@ resources: # timeout_seconds has implicit default of 0 (Go zero value) - field: timeout_seconds values: [0] - - field: "tasks[*].timeout_seconds" + - field: tasks[*].timeout_seconds values: [0] - - field: "tasks[*].for_each_task.task.timeout_seconds" + - field: tasks[*].for_each_task.task.timeout_seconds values: [0] # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L521 # s.SchemaPath("task", "notebook_task", "source").SetSuppressDiff() - - field: "tasks[*].notebook_task.source" - - field: "tasks[*].for_each_task.task.notebook_task.source" + - field: tasks[*].notebook_task.source + - field: tasks[*].for_each_task.task.notebook_task.source # Same as clusters.data_security_mode: backend sets this when not specified - - field: "tasks[*].new_cluster.data_security_mode" - - field: "job_clusters[*].new_cluster.data_security_mode" + - field: tasks[*].new_cluster.data_security_mode + - field: job_clusters[*].new_cluster.data_security_mode pipelines: recreate_on_changes: @@ -110,6 +110,7 @@ resources: # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/pipelines/resource_pipeline.go#L209 - field: ingestion_definition.ingest_from_uc_foreign_catalog reason: immutable + ignore_remote_changes: # "id" is handled in a special way before any fields changed # However, it is also part of RemotePipeline via CreatePipeline. @@ -118,10 +119,12 @@ resources: reason: "!drop" - field: run_as reason: not_returned_by_api + ignore_local_changes: # "id" is output-only, providing it in config would be a mistake - field: id reason: "!drop" + backend_defaults: # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/pipelines/resource_pipeline.go#L254 # s.SchemaPath("edition").SetDefault("ADVANCED") @@ -195,15 +198,15 @@ resources: # common.CustomizeSchemaPath(m, "config", "traffic_config").SetComputed() # Routes have custom SuppressDiff (lines 387-388) - field: config.traffic_config - reason: "managed" + reason: managed backend_defaults: # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/serving/resource_model_serving.go#L383 # common.CustomizeSchemaPath(m, "config", "served_entities", "name").SetComputed() - - field: "config.served_entities[*].name" + - field: config.served_entities[*].name # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/serving/resource_model_serving.go#L384 # common.CustomizeSchemaPath(m, "config", "served_entities", "workload_type").SetComputed() - - field: "config.served_entities[*].workload_type" + - field: config.served_entities[*].workload_type # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/serving/resource_model_serving.go#L372 # common.CustomizeSchemaPath(m, "config", "auto_capture_config", "enabled").SetComputed() @@ -367,16 +370,16 @@ resources: # s.SchemaPath("azure_attributes").SetSuppressDiff() # s.SchemaPath("gcp_attributes").SetSuppressDiff() - field: aws_attributes - reason: "managed" + reason: managed - field: azure_attributes - reason: "managed" + reason: managed - field: gcp_attributes - reason: "managed" + reason: managed # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L331 # s.SchemaPath("enable_elastic_disk").SetComputed() - field: enable_elastic_disk - reason: "managed" + reason: managed backend_defaults: # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L320-L324 @@ -393,17 +396,17 @@ resources: # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L62 # common.CustomizeSchemaPath(m, "channel").SetSuppressDiff() - field: channel - reason: "managed" + reason: managed # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L82 # common.CustomizeSchemaPath(m, "tags").SetSuppressDiff() - field: tags - reason: "managed" + reason: managed # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L85-L87 # common.CustomizeSchemaPath(m, "warehouse_type").SetSuppressDiff() - field: warehouse_type - reason: "managed" + reason: managed backend_defaults: # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L61 From 984f214c5f1c06e32034a7b85ee877e53ee81f24 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 11 Feb 2026 13:53:19 +0100 Subject: [PATCH 08/21] update --- bundle/direct/dresources/resources.yml | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/bundle/direct/dresources/resources.yml b/bundle/direct/dresources/resources.yml index 7fcd58f436..3d68e6843a 100644 --- a/bundle/direct/dresources/resources.yml +++ b/bundle/direct/dresources/resources.yml @@ -17,14 +17,16 @@ resources: jobs: ignore_remote_changes: + # Same as clusters.{aws,azure,gcp}_attributes — see clusters/resource_cluster.go#L361-L363 + # s.SchemaPath("aws_attributes").SetSuppressDiff() + # s.SchemaPath("azure_attributes").SetSuppressDiff() + # s.SchemaPath("gcp_attributes").SetSuppressDiff() - field: tasks[*].new_cluster.aws_attributes - # These are not "output_only", because they can be set by the user as well. reason: managed - field: tasks[*].new_cluster.azure_attributes reason: managed - field: tasks[*].new_cluster.gcp_attributes reason: managed - - field: job_clusters[*].new_cluster.aws_attributes reason: managed - field: job_clusters[*].new_cluster.azure_attributes @@ -32,12 +34,12 @@ resources: - field: job_clusters[*].new_cluster.gcp_attributes reason: managed + backend_defaults: + # Same as clusters.enable_elastic_disk — see clusters/resource_cluster.go#L331 + # s.SchemaPath("enable_elastic_disk").SetComputed() - field: tasks[*].new_cluster.enable_elastic_disk - reason: managed - field: job_clusters[*].new_cluster.enable_elastic_disk - reason: managed - backend_defaults: # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L570 # s.SchemaPath("max_concurrent_runs").SetDefault(1) - field: max_concurrent_runs @@ -376,20 +378,20 @@ resources: - field: gcp_attributes reason: managed + backend_defaults: # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L331 # s.SchemaPath("enable_elastic_disk").SetComputed() - field: enable_elastic_disk - reason: managed - backend_defaults: # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L320-L324 # s.AddNewField("autotermination_minutes", &schema.Schema{Default: 60}) - field: autotermination_minutes values: [60] - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L109-L118 - # DataSecurityModeDiffSuppressFunc: suppress when old != "" && new == "" - - field: data_security_mode + # We have custom handler for this in cluster.go + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L109-L118 + # DataSecurityModeDiffSuppressFunc: suppress when old != "" && new == "" + #- field: data_security_mode sql_warehouses: ignore_remote_changes: From 4292c877fc092f6cdd2f79e7db09a9d5626e55c1 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 11 Feb 2026 13:56:27 +0100 Subject: [PATCH 09/21] remove timeout_seconds --- bundle/direct/dresources/resources.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/bundle/direct/dresources/resources.yml b/bundle/direct/dresources/resources.yml index 3d68e6843a..f60516dc4d 100644 --- a/bundle/direct/dresources/resources.yml +++ b/bundle/direct/dresources/resources.yml @@ -75,14 +75,6 @@ resources: - field: "tasks[*].for_each_task.task.run_if" values: ["ALL_SUCCESS"] - # timeout_seconds has implicit default of 0 (Go zero value) - - field: timeout_seconds - values: [0] - - field: tasks[*].timeout_seconds - values: [0] - - field: tasks[*].for_each_task.task.timeout_seconds - values: [0] - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L521 # s.SchemaPath("task", "notebook_task", "source").SetSuppressDiff() - field: tasks[*].notebook_task.source From 32030de8f8bc4c26bc8eb1194647ea08df88c660 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 11 Feb 2026 14:00:25 +0100 Subject: [PATCH 10/21] update test out + lint --- .../whl_dynamic/out.plan_update.direct.json | 4 ++-- .../bundle/migrate/basic/out.plan_update.json | 8 ++++---- .../default-python/out.plan_after_deploy.json | 10 +++++----- .../out.plan_after_migration.json | 10 +++++----- .../bundle/migrate/default-python/output.txt | 20 +++++++++---------- .../delete_task/out.plan_update.direct.json | 2 +- .../out.plan.direct.json | 4 ++-- .../out.plan_post_update.direct.json | 2 +- .../out.plan.direct.json | 6 +++--- .../jobs/added_remotely/out.plan.direct.json | 2 +- .../local/out.plan_update.direct.json | 2 +- .../out.plan_restore.direct.json | 2 +- .../update/out.plan_delete_all.direct.json | 2 +- .../update/out.plan_delete_one.direct.json | 2 +- .../update/out.plan_post_create.direct.json | 2 +- .../jobs/update/out.plan_restore.direct.json | 2 +- .../update/out.plan_set_empty.direct.json | 2 +- .../jobs/update/out.plan_update.direct.json | 2 +- .../out.plan_after_deploy_dev.direct.json | 10 +++++----- .../out.plan_after_deploy_prod.direct.json | 10 +++++----- .../out.plan_after_deploy_dev.direct.json | 8 ++++---- .../out.plan_after_deploy_prod.direct.json | 8 ++++---- bundle/deployplan/plan.go | 2 +- 23 files changed, 61 insertions(+), 61 deletions(-) diff --git a/acceptance/bundle/artifacts/whl_dynamic/out.plan_update.direct.json b/acceptance/bundle/artifacts/whl_dynamic/out.plan_update.direct.json index ab374309c4..86957a974c 100644 --- a/acceptance/bundle/artifacts/whl_dynamic/out.plan_update.direct.json +++ b/acceptance/bundle/artifacts/whl_dynamic/out.plan_update.direct.json @@ -172,7 +172,7 @@ }, "tasks[task_key='ServerlessTestTask'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='ServerlessTestTask'].timeout_seconds": { @@ -199,7 +199,7 @@ }, "tasks[task_key='TestTask'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='TestTask'].timeout_seconds": { diff --git a/acceptance/bundle/migrate/basic/out.plan_update.json b/acceptance/bundle/migrate/basic/out.plan_update.json index 5c7bb6e043..c249c7b850 100644 --- a/acceptance/bundle/migrate/basic/out.plan_update.json +++ b/acceptance/bundle/migrate/basic/out.plan_update.json @@ -80,12 +80,12 @@ }, "tasks[task_key='main'].notebook_task.source": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "WORKSPACE" }, "tasks[task_key='main'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='main'].timeout_seconds": { @@ -202,7 +202,7 @@ }, "storage": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "dbfs:/pipelines/[UUID]" }, "tags['myjob_name']": { @@ -237,7 +237,7 @@ "changes": { "storage_location": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "s3://deco-uc-prod-isolated-aws-us-east-1/metastore/[UUID]/volumes/[UUID]" } } diff --git a/acceptance/bundle/migrate/default-python/out.plan_after_deploy.json b/acceptance/bundle/migrate/default-python/out.plan_after_deploy.json index 15e6c7379a..67b82cbabb 100644 --- a/acceptance/bundle/migrate/default-python/out.plan_after_deploy.json +++ b/acceptance/bundle/migrate/default-python/out.plan_after_deploy.json @@ -242,12 +242,12 @@ }, "tasks[task_key='notebook_task'].notebook_task.source": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "WORKSPACE" }, "tasks[task_key='notebook_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='notebook_task'].timeout_seconds": { @@ -268,7 +268,7 @@ }, "tasks[task_key='python_wheel_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='python_wheel_task'].timeout_seconds": { @@ -283,7 +283,7 @@ }, "tasks[task_key='refresh_pipeline'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='refresh_pipeline'].timeout_seconds": { @@ -342,7 +342,7 @@ "changes": { "storage": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "dbfs:/pipelines/[UUID]" } } diff --git a/acceptance/bundle/migrate/default-python/out.plan_after_migration.json b/acceptance/bundle/migrate/default-python/out.plan_after_migration.json index 527a30cf67..5f228bec81 100644 --- a/acceptance/bundle/migrate/default-python/out.plan_after_migration.json +++ b/acceptance/bundle/migrate/default-python/out.plan_after_migration.json @@ -242,12 +242,12 @@ }, "tasks[task_key='notebook_task'].notebook_task.source": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "WORKSPACE" }, "tasks[task_key='notebook_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='notebook_task'].timeout_seconds": { @@ -268,7 +268,7 @@ }, "tasks[task_key='python_wheel_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='python_wheel_task'].timeout_seconds": { @@ -283,7 +283,7 @@ }, "tasks[task_key='refresh_pipeline'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='refresh_pipeline'].timeout_seconds": { @@ -342,7 +342,7 @@ "changes": { "storage": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "dbfs:/pipelines/[UUID]" } } diff --git a/acceptance/bundle/migrate/default-python/output.txt b/acceptance/bundle/migrate/default-python/output.txt index 539235fab3..dcdd47e087 100644 --- a/acceptance/bundle/migrate/default-python/output.txt +++ b/acceptance/bundle/migrate/default-python/output.txt @@ -92,12 +92,12 @@ Building python_artifact... }, "tasks[task_key='notebook_task'].notebook_task.source": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "WORKSPACE" }, "tasks[task_key='notebook_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='notebook_task'].timeout_seconds": { @@ -118,7 +118,7 @@ Building python_artifact... }, "tasks[task_key='python_wheel_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='python_wheel_task'].timeout_seconds": { @@ -133,7 +133,7 @@ Building python_artifact... }, "tasks[task_key='refresh_pipeline'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='refresh_pipeline'].timeout_seconds": { @@ -155,7 +155,7 @@ Building python_artifact... { "storage": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "dbfs:/pipelines/[UUID]" } } @@ -211,12 +211,12 @@ Building python_artifact... }, "tasks[task_key='notebook_task'].notebook_task.source": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "WORKSPACE" }, "tasks[task_key='notebook_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='notebook_task'].timeout_seconds": { @@ -237,7 +237,7 @@ Building python_artifact... }, "tasks[task_key='python_wheel_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='python_wheel_task'].timeout_seconds": { @@ -252,7 +252,7 @@ Building python_artifact... }, "tasks[task_key='refresh_pipeline'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='refresh_pipeline'].timeout_seconds": { @@ -274,7 +274,7 @@ Building python_artifact... { "storage": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "dbfs:/pipelines/[UUID]" } } diff --git a/acceptance/bundle/resources/jobs/delete_task/out.plan_update.direct.json b/acceptance/bundle/resources/jobs/delete_task/out.plan_update.direct.json index f84c096a34..929dfdff92 100644 --- a/acceptance/bundle/resources/jobs/delete_task/out.plan_update.direct.json +++ b/acceptance/bundle/resources/jobs/delete_task/out.plan_update.direct.json @@ -147,7 +147,7 @@ }, "tasks[task_key='TestTask2'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='TestTask2'].timeout_seconds": { diff --git a/acceptance/bundle/resources/jobs/on_failure_empty_slice/out.plan.direct.json b/acceptance/bundle/resources/jobs/on_failure_empty_slice/out.plan.direct.json index 00230b72bb..816bda2d67 100644 --- a/acceptance/bundle/resources/jobs/on_failure_empty_slice/out.plan.direct.json +++ b/acceptance/bundle/resources/jobs/on_failure_empty_slice/out.plan.direct.json @@ -11,12 +11,12 @@ }, "tasks[task_key='usage_logs_grants'].notebook_task.source": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "WORKSPACE" }, "tasks[task_key='usage_logs_grants'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='usage_logs_grants'].timeout_seconds": { diff --git a/acceptance/bundle/resources/jobs/remote_add_tag/out.plan_post_update.direct.json b/acceptance/bundle/resources/jobs/remote_add_tag/out.plan_post_update.direct.json index bf51ae0831..15963bc007 100644 --- a/acceptance/bundle/resources/jobs/remote_add_tag/out.plan_post_update.direct.json +++ b/acceptance/bundle/resources/jobs/remote_add_tag/out.plan_post_update.direct.json @@ -98,7 +98,7 @@ }, "tasks[task_key='TestTask'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='TestTask'].timeout_seconds": { diff --git a/acceptance/bundle/resources/jobs/remote_matches_config/out.plan.direct.json b/acceptance/bundle/resources/jobs/remote_matches_config/out.plan.direct.json index 61107b5a0c..448eafd5d3 100644 --- a/acceptance/bundle/resources/jobs/remote_matches_config/out.plan.direct.json +++ b/acceptance/bundle/resources/jobs/remote_matches_config/out.plan.direct.json @@ -80,7 +80,7 @@ }, "tasks[task_key='main_task'].new_cluster.data_security_mode": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "SINGLE_USER" }, "tasks[task_key='main_task'].new_cluster.enable_elastic_disk": { @@ -90,12 +90,12 @@ }, "tasks[task_key='main_task'].notebook_task.source": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "WORKSPACE" }, "tasks[task_key='main_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='main_task'].timeout_seconds": { diff --git a/acceptance/bundle/resources/permissions/jobs/added_remotely/out.plan.direct.json b/acceptance/bundle/resources/permissions/jobs/added_remotely/out.plan.direct.json index 941b23e5c8..c5e456b5c0 100644 --- a/acceptance/bundle/resources/permissions/jobs/added_remotely/out.plan.direct.json +++ b/acceptance/bundle/resources/permissions/jobs/added_remotely/out.plan.direct.json @@ -51,7 +51,7 @@ }, "tasks[task_key='main'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='main'].timeout_seconds": { diff --git a/acceptance/bundle/resources/permissions/jobs/delete_one/local/out.plan_update.direct.json b/acceptance/bundle/resources/permissions/jobs/delete_one/local/out.plan_update.direct.json index 12cb612f48..1914747039 100644 --- a/acceptance/bundle/resources/permissions/jobs/delete_one/local/out.plan_update.direct.json +++ b/acceptance/bundle/resources/permissions/jobs/delete_one/local/out.plan_update.direct.json @@ -51,7 +51,7 @@ }, "tasks[task_key='main'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='main'].timeout_seconds": { diff --git a/acceptance/bundle/resources/permissions/jobs/deleted_remotely/out.plan_restore.direct.json b/acceptance/bundle/resources/permissions/jobs/deleted_remotely/out.plan_restore.direct.json index f818786292..6779ef9018 100644 --- a/acceptance/bundle/resources/permissions/jobs/deleted_remotely/out.plan_restore.direct.json +++ b/acceptance/bundle/resources/permissions/jobs/deleted_remotely/out.plan_restore.direct.json @@ -51,7 +51,7 @@ }, "tasks[task_key='main'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='main'].timeout_seconds": { diff --git a/acceptance/bundle/resources/permissions/jobs/update/out.plan_delete_all.direct.json b/acceptance/bundle/resources/permissions/jobs/update/out.plan_delete_all.direct.json index d8aa0e3c54..06e3eed8c7 100644 --- a/acceptance/bundle/resources/permissions/jobs/update/out.plan_delete_all.direct.json +++ b/acceptance/bundle/resources/permissions/jobs/update/out.plan_delete_all.direct.json @@ -51,7 +51,7 @@ }, "tasks[task_key='main'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='main'].timeout_seconds": { diff --git a/acceptance/bundle/resources/permissions/jobs/update/out.plan_delete_one.direct.json b/acceptance/bundle/resources/permissions/jobs/update/out.plan_delete_one.direct.json index 82ecdbde2b..c15dd9a21c 100644 --- a/acceptance/bundle/resources/permissions/jobs/update/out.plan_delete_one.direct.json +++ b/acceptance/bundle/resources/permissions/jobs/update/out.plan_delete_one.direct.json @@ -51,7 +51,7 @@ }, "tasks[task_key='main'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='main'].timeout_seconds": { diff --git a/acceptance/bundle/resources/permissions/jobs/update/out.plan_post_create.direct.json b/acceptance/bundle/resources/permissions/jobs/update/out.plan_post_create.direct.json index ba7bd1fa01..44682af8c0 100644 --- a/acceptance/bundle/resources/permissions/jobs/update/out.plan_post_create.direct.json +++ b/acceptance/bundle/resources/permissions/jobs/update/out.plan_post_create.direct.json @@ -51,7 +51,7 @@ }, "tasks[task_key='main'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='main'].timeout_seconds": { diff --git a/acceptance/bundle/resources/permissions/jobs/update/out.plan_restore.direct.json b/acceptance/bundle/resources/permissions/jobs/update/out.plan_restore.direct.json index 2fd7740fa3..b46b11176f 100644 --- a/acceptance/bundle/resources/permissions/jobs/update/out.plan_restore.direct.json +++ b/acceptance/bundle/resources/permissions/jobs/update/out.plan_restore.direct.json @@ -51,7 +51,7 @@ }, "tasks[task_key='main'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='main'].timeout_seconds": { diff --git a/acceptance/bundle/resources/permissions/jobs/update/out.plan_set_empty.direct.json b/acceptance/bundle/resources/permissions/jobs/update/out.plan_set_empty.direct.json index ff650d6c00..0d192dd875 100644 --- a/acceptance/bundle/resources/permissions/jobs/update/out.plan_set_empty.direct.json +++ b/acceptance/bundle/resources/permissions/jobs/update/out.plan_set_empty.direct.json @@ -51,7 +51,7 @@ }, "tasks[task_key='main'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='main'].timeout_seconds": { diff --git a/acceptance/bundle/resources/permissions/jobs/update/out.plan_update.direct.json b/acceptance/bundle/resources/permissions/jobs/update/out.plan_update.direct.json index 6fdb4e8387..20cbccb035 100644 --- a/acceptance/bundle/resources/permissions/jobs/update/out.plan_update.direct.json +++ b/acceptance/bundle/resources/permissions/jobs/update/out.plan_update.direct.json @@ -51,7 +51,7 @@ }, "tasks[task_key='main'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='main'].timeout_seconds": { diff --git a/acceptance/bundle/templates/default-python/classic/out.plan_after_deploy_dev.direct.json b/acceptance/bundle/templates/default-python/classic/out.plan_after_deploy_dev.direct.json index ab9cd13fe9..2c7d9da5a7 100644 --- a/acceptance/bundle/templates/default-python/classic/out.plan_after_deploy_dev.direct.json +++ b/acceptance/bundle/templates/default-python/classic/out.plan_after_deploy_dev.direct.json @@ -242,12 +242,12 @@ }, "tasks[task_key='notebook_task'].notebook_task.source": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "WORKSPACE" }, "tasks[task_key='notebook_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='notebook_task'].timeout_seconds": { @@ -268,7 +268,7 @@ }, "tasks[task_key='python_wheel_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='python_wheel_task'].timeout_seconds": { @@ -283,7 +283,7 @@ }, "tasks[task_key='refresh_pipeline'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='refresh_pipeline'].timeout_seconds": { @@ -342,7 +342,7 @@ "changes": { "storage": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "dbfs:/pipelines/[UUID]" } } diff --git a/acceptance/bundle/templates/default-python/classic/out.plan_after_deploy_prod.direct.json b/acceptance/bundle/templates/default-python/classic/out.plan_after_deploy_prod.direct.json index fcb6c73404..d31f339a20 100644 --- a/acceptance/bundle/templates/default-python/classic/out.plan_after_deploy_prod.direct.json +++ b/acceptance/bundle/templates/default-python/classic/out.plan_after_deploy_prod.direct.json @@ -135,12 +135,12 @@ }, "tasks[task_key='notebook_task'].notebook_task.source": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "WORKSPACE" }, "tasks[task_key='notebook_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='notebook_task'].timeout_seconds": { @@ -155,7 +155,7 @@ }, "tasks[task_key='python_wheel_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='python_wheel_task'].timeout_seconds": { @@ -170,7 +170,7 @@ }, "tasks[task_key='refresh_pipeline'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='refresh_pipeline'].timeout_seconds": { @@ -243,7 +243,7 @@ "changes": { "storage": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "dbfs:/pipelines/[UUID]" } } diff --git a/acceptance/bundle/templates/default-python/serverless/out.plan_after_deploy_dev.direct.json b/acceptance/bundle/templates/default-python/serverless/out.plan_after_deploy_dev.direct.json index 29887dea16..4c4d021866 100644 --- a/acceptance/bundle/templates/default-python/serverless/out.plan_after_deploy_dev.direct.json +++ b/acceptance/bundle/templates/default-python/serverless/out.plan_after_deploy_dev.direct.json @@ -124,12 +124,12 @@ }, "tasks[task_key='notebook_task'].notebook_task.source": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "WORKSPACE" }, "tasks[task_key='notebook_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='notebook_task'].timeout_seconds": { @@ -144,7 +144,7 @@ }, "tasks[task_key='python_wheel_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='python_wheel_task'].timeout_seconds": { @@ -159,7 +159,7 @@ }, "tasks[task_key='refresh_pipeline'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='refresh_pipeline'].timeout_seconds": { diff --git a/acceptance/bundle/templates/default-python/serverless/out.plan_after_deploy_prod.direct.json b/acceptance/bundle/templates/default-python/serverless/out.plan_after_deploy_prod.direct.json index 92a6cc7464..812094baeb 100644 --- a/acceptance/bundle/templates/default-python/serverless/out.plan_after_deploy_prod.direct.json +++ b/acceptance/bundle/templates/default-python/serverless/out.plan_after_deploy_prod.direct.json @@ -121,12 +121,12 @@ }, "tasks[task_key='notebook_task'].notebook_task.source": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "WORKSPACE" }, "tasks[task_key='notebook_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='notebook_task'].timeout_seconds": { @@ -141,7 +141,7 @@ }, "tasks[task_key='python_wheel_task'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='python_wheel_task'].timeout_seconds": { @@ -156,7 +156,7 @@ }, "tasks[task_key='refresh_pipeline'].run_if": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "ALL_SUCCESS" }, "tasks[task_key='refresh_pipeline'].timeout_seconds": { diff --git a/bundle/deployplan/plan.go b/bundle/deployplan/plan.go index 48b3285f4c..e0dcd9b288 100644 --- a/bundle/deployplan/plan.go +++ b/bundle/deployplan/plan.go @@ -101,7 +101,7 @@ const ( ReasonBackendDefault = "backend_default" ReasonAlias = "alias" ReasonRemoteAlreadySet = "remote_already_set" - ReasonEmpty = "empty" + ReasonEmpty = "empty" ReasonCustom = "custom" // Special reason that results in removing this change from the plan From bd1e06bf63aeb5b7d30245957de9e854d363a5ab Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 11 Feb 2026 16:29:35 +0100 Subject: [PATCH 11/21] restore clusters/deploy/data_security_mode --- .../resources/clusters/deploy/data_security_mode/output.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/acceptance/bundle/resources/clusters/deploy/data_security_mode/output.txt b/acceptance/bundle/resources/clusters/deploy/data_security_mode/output.txt index 0a99281581..9a6773a754 100644 --- a/acceptance/bundle/resources/clusters/deploy/data_security_mode/output.txt +++ b/acceptance/bundle/resources/clusters/deploy/data_security_mode/output.txt @@ -6,9 +6,7 @@ Updating deployment state... Deployment complete! >>> [CLI] bundle plan -update clusters.test_cluster - -Plan: 0 to add, 1 to change, 0 to delete, 0 unchanged +Plan: 0 to add, 0 to change, 0 to delete, 1 unchanged >>> [CLI] bundle deploy Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/[UNIQUE_NAME]/files... From ff77a16ea99fc491e2c4da09a95244f7dec1a350 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 11 Feb 2026 18:03:45 +0100 Subject: [PATCH 12/21] Update resources.yml: add missing backend-set fields, remove dead defaults MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cross-referenced terraform-provider-databricks source (SetComputed, SetSuppressDiff, SetForceNew) against resources.yml to fix gaps. Added backend_defaults (SetComputed/SetSuppressDiff — backend-set fields): - clusters: enable_local_disk_encryption, node_type_id, driver_node_type_id, driver_instance_pool_id - jobs: run_as, spark_python_task.source, sql_task.file.source, dbt_task.source (+ for_each_task variants for all), new_cluster computed fields matching clusters - pipelines: event_log.catalog, event_log.schema, cluster computed fields - sql_warehouses: enable_serverless_compute - experiments: artifact_location Added ignore_remote_changes: - sql_warehouses: min_num_clusters (SetSuppressDiff) - quality_monitors: skip_builtin_dashboard (not returned by API) Added recreate_on_changes: - pipelines: gateway_definition.{connection_id,connection_name, gateway_storage_catalog,gateway_storage_schema}, ingestion_definition.ingest_from_uc_foreign_catalog Removed dead backend_defaults — these are TF client-side SetDefault() values already applied by resource_mutator.go, so the field is never nil and backend_defaults (which triggers on old=nil AND new=nil) never fires: - jobs: max_concurrent_runs, schedule/trigger/continuous.pause_status - pipelines: edition, channel - dashboards: embed_credentials (also had wrong value: yml said true, mutator sets false) - clusters: autotermination_minutes - sql_warehouses: auto_stop_mins, enable_photon, max_num_clusters, spot_instance_policy Co-Authored-By: Claude Opus 4.6 --- bundle/direct/dresources/resources.yml | 153 +++++++++++++++---------- 1 file changed, 94 insertions(+), 59 deletions(-) diff --git a/bundle/direct/dresources/resources.yml b/bundle/direct/dresources/resources.yml index f60516dc4d..83891eaf4b 100644 --- a/bundle/direct/dresources/resources.yml +++ b/bundle/direct/dresources/resources.yml @@ -40,31 +40,31 @@ resources: - field: tasks[*].new_cluster.enable_elastic_disk - field: job_clusters[*].new_cluster.enable_elastic_disk - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L570 - # s.SchemaPath("max_concurrent_runs").SetDefault(1) - - field: max_concurrent_runs - values: [1] + # Same as clusters.enable_local_disk_encryption — see clusters/resource_cluster.go#L332 + # s.SchemaPath("enable_local_disk_encryption").SetComputed() + - field: tasks[*].new_cluster.enable_local_disk_encryption + - field: job_clusters[*].new_cluster.enable_local_disk_encryption + + # Same as clusters.node_type_id — see clusters/resource_cluster.go#L333 + # s.SchemaPath("node_type_id").SetComputed() + - field: tasks[*].new_cluster.node_type_id + - field: job_clusters[*].new_cluster.node_type_id + + # Same as clusters.driver_node_type_id — see clusters/resource_cluster.go#L334 + # s.SchemaPath("driver_node_type_id").SetComputed() + - field: tasks[*].new_cluster.driver_node_type_id + - field: job_clusters[*].new_cluster.driver_node_type_id + + # Same as clusters.driver_instance_pool_id — see clusters/resource_cluster.go#L335 + # s.SchemaPath("driver_instance_pool_id").SetComputed() + - field: tasks[*].new_cluster.driver_instance_pool_id + - field: job_clusters[*].new_cluster.driver_instance_pool_id # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L531 # s.SchemaPath("format").SetComputed() - field: format values: ["MULTI_TASK", "SINGLE_TASK"] - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L534 - # s.SchemaPath("schedule", "pause_status").SetDefault("UNPAUSED") - - field: schedule.pause_status - values: ["UNPAUSED"] - - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L535 - # s.SchemaPath("trigger", "pause_status").SetDefault("UNPAUSED") - - field: trigger.pause_status - values: ["UNPAUSED"] - - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L536 - # s.SchemaPath("continuous", "pause_status").SetDefault("UNPAUSED") - - field: continuous.pause_status - values: ["UNPAUSED"] - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L639 # s.SchemaPath("task", "run_if").SetSuppressDiffWithDefault(jobs.RunIfAllSuccess) - field: "tasks[*].run_if" @@ -75,10 +75,23 @@ resources: - field: "tasks[*].for_each_task.task.run_if" values: ["ALL_SUCCESS"] - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L521 + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L527 + # s.SchemaPath("run_as").SetComputed() + - field: run_as + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/jobs/resource_job.go#L521-L524 # s.SchemaPath("task", "notebook_task", "source").SetSuppressDiff() + # s.SchemaPath("task", "spark_python_task", "source").SetSuppressDiff() + # s.SchemaPath("task", "sql_task", "file", "source").SetSuppressDiff() + # s.SchemaPath("task", "dbt_task", "source").SetSuppressDiff() - field: tasks[*].notebook_task.source - field: tasks[*].for_each_task.task.notebook_task.source + - field: tasks[*].spark_python_task.source + - field: tasks[*].for_each_task.task.spark_python_task.source + - field: tasks[*].sql_task.file.source + - field: tasks[*].for_each_task.task.sql_task.file.source + - field: tasks[*].dbt_task.source + - field: tasks[*].for_each_task.task.dbt_task.source # Same as clusters.data_security_mode: backend sets this when not specified - field: tasks[*].new_cluster.data_security_mode @@ -104,6 +117,18 @@ resources: # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/pipelines/resource_pipeline.go#L209 - field: ingestion_definition.ingest_from_uc_foreign_catalog reason: immutable + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/pipelines/resource_pipeline.go#L204 + - field: gateway_definition.connection_id + reason: immutable + - field: gateway_definition.connection_name + reason: immutable + - field: gateway_definition.gateway_storage_catalog + reason: immutable + - field: gateway_definition.gateway_storage_schema + reason: immutable + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/pipelines/resource_pipeline.go#L209 + - field: ingestion_definition.ingest_from_uc_foreign_catalog + reason: immutable ignore_remote_changes: # "id" is handled in a special way before any fields changed @@ -120,16 +145,6 @@ resources: reason: "!drop" backend_defaults: - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/pipelines/resource_pipeline.go#L254 - # s.SchemaPath("edition").SetDefault("ADVANCED") - - field: edition - values: ["ADVANCED"] - - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/pipelines/resource_pipeline.go#L255 - # s.SchemaPath("channel").SetDefault("CURRENT") - - field: channel - values: ["CURRENT"] - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/pipelines/resource_pipeline.go#L238 # s.SchemaPath("storage").SetCustomSuppressDiff(suppressStorageDiff) # Backend generates storage path like dbfs:/pipelines/ when not set by user. @@ -138,6 +153,24 @@ resources: # root_path is computed by the backend when not set by user. - field: root_path + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/pipelines/resource_pipeline.go#L218 + # s.SchemaPath("cluster", "node_type_id").SetComputed() + - field: clusters[*].node_type_id + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/pipelines/resource_pipeline.go#L219 + # s.SchemaPath("cluster", "driver_node_type_id").SetComputed() + - field: clusters[*].driver_node_type_id + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/pipelines/resource_pipeline.go#L220 + # s.SchemaPath("cluster", "enable_local_disk_encryption").SetComputed() + - field: clusters[*].enable_local_disk_encryption + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/pipelines/resource_pipeline.go#L229-L230 + # s.SchemaPath("event_log", "catalog").SetComputed() + # s.SchemaPath("event_log", "schema").SetComputed() + - field: event_log.catalog + - field: event_log.schema + models: recreate_on_changes: # Recreate matches current behavior of Terraform. It is possible to rename without recreate @@ -163,6 +196,10 @@ resources: recreate_on_changes: - field: artifact_location reason: immutable + backend_defaults: + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/mlflow/resource_mlflow_experiment.go#L34 + # SetForceNew().SetSuppressDiff(): backend generates artifact_location when not set by user + - field: artifact_location ignore_remote_changes: # Tags updates are not supported by TF. This mirrors that behaviour. - field: tags @@ -252,6 +289,10 @@ resources: ignore_remote_changes: - field: warehouse_id reason: not_returned_by_api + # skip_builtin_dashboard is input-only, not returned by the Get API. + # TF preserves it from state; see resource_quality_monitor.go. + - field: skip_builtin_dashboard + reason: not_returned_by_api catalogs: recreate_on_changes: @@ -310,12 +351,6 @@ resources: - field: storage_location dashboards: - backend_defaults: - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/dashboards/resource_dashboard.go#L69 - # s.SchemaPath("embed_credentials").SetDefault(true) - - field: embed_credentials - values: [true] - ignore_remote_changes: # "serialized_dashboard" locally and remotely will have different contents # We only need to rely on etag here, and can skip this field for diff computation. @@ -375,10 +410,21 @@ resources: # s.SchemaPath("enable_elastic_disk").SetComputed() - field: enable_elastic_disk - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L320-L324 - # s.AddNewField("autotermination_minutes", &schema.Schema{Default: 60}) - - field: autotermination_minutes - values: [60] + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L332 + # s.SchemaPath("enable_local_disk_encryption").SetComputed() + - field: enable_local_disk_encryption + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L333 + # s.SchemaPath("node_type_id").SetComputed() + - field: node_type_id + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L334 + # s.SchemaPath("driver_node_type_id").SetComputed() + - field: driver_node_type_id + + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L335 + # s.SchemaPath("driver_instance_pool_id").SetComputed() + - field: driver_instance_pool_id # We have custom handler for this in cluster.go # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L109-L118 @@ -402,26 +448,15 @@ resources: - field: warehouse_type reason: managed + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L75 + # common.CustomizeSchemaPath(m, "min_num_clusters").SetSuppressDiff() + - field: min_num_clusters + reason: managed + backend_defaults: - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L61 - # common.SetDefault(m["auto_stop_mins"], 120) - - field: auto_stop_mins - values: [120] - - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L68 - # common.SetDefault(m["enable_photon"], true) - - field: enable_photon - values: [true] - - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L72 - # common.SetDefault(m["max_num_clusters"], 1) - - field: max_num_clusters - values: [1] - - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L80 - # common.SetDefault(m["spot_instance_policy"], "COST_OPTIMIZED") - - field: spot_instance_policy - values: ["COST_OPTIMIZED"] + # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/sql/resource_sql_endpoint.go#L69 + # m["enable_serverless_compute"].Computed = true + - field: enable_serverless_compute postgres_projects: recreate_on_changes: From 6dce636dfba94289398d11d8af204cd1e391c149 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 11 Feb 2026 18:17:53 +0100 Subject: [PATCH 13/21] revert interactive_cluster --- .../bundle/integration_whl/interactive_cluster/output.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acceptance/bundle/integration_whl/interactive_cluster/output.txt b/acceptance/bundle/integration_whl/interactive_cluster/output.txt index 8ebcc456ad..57beb13d02 100644 --- a/acceptance/bundle/integration_whl/interactive_cluster/output.txt +++ b/acceptance/bundle/integration_whl/interactive_cluster/output.txt @@ -61,7 +61,7 @@ Run URL: [DATABRICKS_URL]/?o=[NUMID]#job/[SOME_OTHER_JOB_ID]/run/[NUMID] [TIMESTAMP] "[default] Test Wheel Job [UNIQUE_NAME]" RUNNING [TIMESTAMP] "[default] Test Wheel Job [UNIQUE_NAME]" TERMINATED SUCCESS -UPDATED MY FUNC +Hello from my func Got arguments: ['my_test_code', 'one', 'two'] From 6e6de6946deeaaebd60e314bc3e12f6a35a377aa Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 18 Feb 2026 12:19:26 +0100 Subject: [PATCH 14/21] update --- .../bundle/config-remote-sync/pipeline_fields/output.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/acceptance/bundle/config-remote-sync/pipeline_fields/output.txt b/acceptance/bundle/config-remote-sync/pipeline_fields/output.txt index ea2c6a557b..86aa02ca29 100644 --- a/acceptance/bundle/config-remote-sync/pipeline_fields/output.txt +++ b/acceptance/bundle/config-remote-sync/pipeline_fields/output.txt @@ -12,7 +12,6 @@ Resource: resources.pipelines.my_pipeline environment.dependencies: replace notifications[0].alerts: replace notifications[0].email_recipients: replace - root_path: add schema: replace tags['foo']: add @@ -23,7 +22,7 @@ Resource: resources.pipelines.my_pipeline >>> diff.py databricks.yml.backup databricks.yml --- databricks.yml.backup +++ databricks.yml -@@ -7,18 +7,25 @@ +@@ -7,18 +7,24 @@ name: test-pipeline-[UNIQUE_NAME] catalog: main - schema: default @@ -47,7 +46,6 @@ Resource: resources.pipelines.my_pipeline path: /Users/{{workspace_user_name}}/notebook + tags: + foo: bar -+ root_path: ./pipeline_root targets: From 6d358933ab6bae00affff2dda76dd4d35cf51cd4 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 18 Feb 2026 12:29:42 +0100 Subject: [PATCH 15/21] add single_user_name --- .../integration_whl/interactive_single_user/out.direct.txt | 2 +- bundle/direct/dresources/resources.yml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/acceptance/bundle/integration_whl/interactive_single_user/out.direct.txt b/acceptance/bundle/integration_whl/interactive_single_user/out.direct.txt index c9ac86bb07..2c32ebd11d 100644 --- a/acceptance/bundle/integration_whl/interactive_single_user/out.direct.txt +++ b/acceptance/bundle/integration_whl/interactive_single_user/out.direct.txt @@ -1,6 +1,6 @@ Hello from my func Got arguments: ['my_test_code', 'one', 'two'] -UPDATED MY FUNC +Hello from my func Got arguments: ['my_test_code', 'one', 'two'] diff --git a/bundle/direct/dresources/resources.yml b/bundle/direct/dresources/resources.yml index 83891eaf4b..4576b0cc33 100644 --- a/bundle/direct/dresources/resources.yml +++ b/bundle/direct/dresources/resources.yml @@ -426,6 +426,10 @@ resources: # s.SchemaPath("driver_instance_pool_id").SetComputed() - field: driver_instance_pool_id + # Terraform currently does not do this, but it is a field with backend default. + # See https://github.com/databricks/cli/issues/4418 + - field: single_user_name + # We have custom handler for this in cluster.go # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/clusters/resource_cluster.go#L109-L118 # DataSecurityModeDiffSuppressFunc: suppress when old != "" && new == "" From 0ed9f5b517c76476d0c41585775cad0ca8478b78 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 18 Feb 2026 12:37:36 +0100 Subject: [PATCH 16/21] Update changelog --- NEXT_CHANGELOG.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index dee38fa687..61b0119eb5 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -5,8 +5,7 @@ ### Bundles * Added support for UC external locations (direct mode only) ([#4484](https://github.com/databricks/cli/pull/4484)) * Log artifact build output in debug mode ([#4208](https://github.com/databricks/cli/pull/4208)) +* Fix bundle init not working in Azure Government ([#4286](https://github.com/databricks/cli/pull/4286)) +* engine/direct: Replace server_side_default with more precise backend_default rule in bundle plan ([#4490](https://github.com/databricks/cli/pull/4490)) ### Dependency updates - -### Bundles -* Fix bundle init not working in Azure Government ([#4286](https://github.com/databricks/cli/pull/4286)) From b86bdb1d017c3f4217823013558b1b95d0381f5a Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 18 Feb 2026 12:40:19 +0100 Subject: [PATCH 17/21] remove root_path --- .../bundle/config-remote-sync/pipeline_fields/output.txt | 4 +++- bundle/direct/dresources/resources.yml | 3 --- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/acceptance/bundle/config-remote-sync/pipeline_fields/output.txt b/acceptance/bundle/config-remote-sync/pipeline_fields/output.txt index 86aa02ca29..ea2c6a557b 100644 --- a/acceptance/bundle/config-remote-sync/pipeline_fields/output.txt +++ b/acceptance/bundle/config-remote-sync/pipeline_fields/output.txt @@ -12,6 +12,7 @@ Resource: resources.pipelines.my_pipeline environment.dependencies: replace notifications[0].alerts: replace notifications[0].email_recipients: replace + root_path: add schema: replace tags['foo']: add @@ -22,7 +23,7 @@ Resource: resources.pipelines.my_pipeline >>> diff.py databricks.yml.backup databricks.yml --- databricks.yml.backup +++ databricks.yml -@@ -7,18 +7,24 @@ +@@ -7,18 +7,25 @@ name: test-pipeline-[UNIQUE_NAME] catalog: main - schema: default @@ -46,6 +47,7 @@ Resource: resources.pipelines.my_pipeline path: /Users/{{workspace_user_name}}/notebook + tags: + foo: bar ++ root_path: ./pipeline_root targets: diff --git a/bundle/direct/dresources/resources.yml b/bundle/direct/dresources/resources.yml index 4576b0cc33..1739418a15 100644 --- a/bundle/direct/dresources/resources.yml +++ b/bundle/direct/dresources/resources.yml @@ -150,9 +150,6 @@ resources: # Backend generates storage path like dbfs:/pipelines/ when not set by user. - field: storage - # root_path is computed by the backend when not set by user. - - field: root_path - # https://github.com/databricks/terraform-provider-databricks/blob/4eba541abe1a9f50993ea7b9dd83874207e224a1/pipelines/resource_pipeline.go#L218 # s.SchemaPath("cluster", "node_type_id").SetComputed() - field: clusters[*].node_type_id From 680f118b9fc10c3c168dc2d3e37005e70f2d37c7 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 18 Feb 2026 13:21:00 +0100 Subject: [PATCH 18/21] update bind test wrt root_path --- .../deployment/bind/pipelines/recreate/out.bind-fail.direct.txt | 1 + .../deployment/bind/pipelines/update/out.bind-fail.direct.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/acceptance/bundle/deployment/bind/pipelines/recreate/out.bind-fail.direct.txt b/acceptance/bundle/deployment/bind/pipelines/recreate/out.bind-fail.direct.txt index 75d0788301..c5e00b49cb 100644 --- a/acceptance/bundle/deployment/bind/pipelines/recreate/out.bind-fail.direct.txt +++ b/acceptance/bundle/deployment/bind/pipelines/recreate/out.bind-fail.direct.txt @@ -8,6 +8,7 @@ Changes detected: ~ edition: null -> "ADVANCED" ~ libraries: [{"glob":{"include":"/Workspace/Users/someuser@databricks.com/lakeflow_pipeline/transformations/**"}},{"glob":{"include":"/Workspace/Users/foo@databricks.com/another/**"}}] -> [{"notebook":{"path":"/Workspace/Users/[USERNAME]/.bundle/test-pipeline-recreate-[UNIQUE_NAME]/default/files/nb"}}] ~ name: "lakeflow-pipeline-[UNIQUE_NAME]" -> "test-pipeline-[UNIQUE_NAME]" + ~ root_path: "/Workspace/Users/someuser@databricks.com/lakeflow_pipeline" -> null ~ storage: "/Shared/old_storage" -> "/Shared/new_storage" Error: This bind operation requires user confirmation, but the current console does not support prompting. Please specify --auto-approve if you would like to skip prompts and proceed. diff --git a/acceptance/bundle/deployment/bind/pipelines/update/out.bind-fail.direct.txt b/acceptance/bundle/deployment/bind/pipelines/update/out.bind-fail.direct.txt index 385516aec5..7b85803529 100644 --- a/acceptance/bundle/deployment/bind/pipelines/update/out.bind-fail.direct.txt +++ b/acceptance/bundle/deployment/bind/pipelines/update/out.bind-fail.direct.txt @@ -9,6 +9,7 @@ Changes detected: ~ edition: null -> "ADVANCED" ~ libraries: [{"glob":{"include":"/Workspace/Users/[USERNAME]/lakeflow_pipeline/transformations/**"}},{"glob":{"include":"/Workspace/Users/foo@databricks.com/another/**"}}] -> [{"notebook":{"path":"/Workspace/Users/[USERNAME]/.bundle/test-pipeline-recreate/default/files/nb"}}] ~ name: "lakeflow-pipeline" -> "test-pipeline" + ~ root_path: "/Workspace/Users/[USERNAME]/lakeflow_pipeline" -> null Error: This bind operation requires user confirmation, but the current console does not support prompting. Please specify --auto-approve if you would like to skip prompts and proceed. From dfe07363219cbcc99e33211a268fe605bebfa68a Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 18 Feb 2026 13:41:06 +0100 Subject: [PATCH 19/21] fix testserver clusters & invariant/no_drift test; real cluster do not have default for data_security_mode --- acceptance/bundle/invariant/no_drift/script | 10 ++++------ libs/testserver/clusters.go | 5 ----- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/acceptance/bundle/invariant/no_drift/script b/acceptance/bundle/invariant/no_drift/script index a5d6967b19..6d11ed7b1c 100644 --- a/acceptance/bundle/invariant/no_drift/script +++ b/acceptance/bundle/invariant/no_drift/script @@ -39,12 +39,10 @@ cat LOG.deploy | contains.py '!panic' '!internal error' > /dev/null # Any failures after this point will be considered as "bug detected" by fuzzer. echo INPUT_CONFIG_OK -$CLI bundle plan -o json &> plan.json -cat plan.json | contains.py '!panic' '!internal error' > /dev/null - # Check both text and JSON plan for no changes # Note, expect that there maybe more than one resource unchanged -$CLI bundle plan | contains.py '!panic' '!internal error' 'Plan: 0 to add, 0 to change, 0 to delete' > LOG.plan +$CLI bundle plan -o json &> LOG.planjson +cat LOG.planjson | contains.py '!panic' '!internal error' > /dev/null +verify_no_drift.py LOG.planjson -$CLI bundle plan -o json > plan.json -verify_no_drift.py plan.json +$CLI bundle plan | contains.py '!panic' '!internal error' 'Plan: 0 to add, 0 to change, 0 to delete' > LOG.plan diff --git a/libs/testserver/clusters.go b/libs/testserver/clusters.go index 9a934324f8..ca900e97a8 100644 --- a/libs/testserver/clusters.go +++ b/libs/testserver/clusters.go @@ -104,11 +104,6 @@ func clusterFixUps(cluster *compute.ClusterDetails) { ) } - if cluster.DataSecurityMode == "" { - cluster.DataSecurityMode = compute.DataSecurityModeSingleUser - cluster.ForceSendFields = append(cluster.ForceSendFields, "DataSecurityMode") - } - cluster.ForceSendFields = append(cluster.ForceSendFields, "EnableElasticDisk") if cluster.DriverNodeTypeId == "" && cluster.NodeTypeId != "" { From 78a84ebbb102e922dc50af5b6b96a7563558b6ba Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 18 Feb 2026 13:45:54 +0100 Subject: [PATCH 20/21] update clusters test --- .../out.plan_.direct.json | 40 ++++--------------- .../update-and-resize-autoscale/output.txt | 1 - .../update-and-resize/out.plan_.direct.json | 30 +++----------- .../deploy/update-and-resize/output.txt | 1 - 4 files changed, 14 insertions(+), 58 deletions(-) diff --git a/acceptance/bundle/resources/clusters/deploy/update-and-resize-autoscale/out.plan_.direct.json b/acceptance/bundle/resources/clusters/deploy/update-and-resize-autoscale/out.plan_.direct.json index 627f4ff3de..ea57340a31 100644 --- a/acceptance/bundle/resources/clusters/deploy/update-and-resize-autoscale/out.plan_.direct.json +++ b/acceptance/bundle/resources/clusters/deploy/update-and-resize-autoscale/out.plan_.direct.json @@ -44,7 +44,6 @@ }, "cluster_id": "[CLUSTER_ID]", "cluster_name": "test-cluster-[UNIQUE_NAME]", - "data_security_mode": "SINGLE_USER", "driver_node_type_id": "[NODE_TYPE_ID]", "enable_elastic_disk": false, "node_type_id": "[NODE_TYPE_ID]", @@ -61,20 +60,15 @@ }, "aws_attributes": { "action": "skip", - "reason": "server_side_default", + "reason": "managed", "remote": { "availability": "SPOT_WITH_FALLBACK", "zone_id": "us-east-1c" } }, - "data_security_mode": { - "action": "skip", - "reason": "server_side_default", - "remote": "SINGLE_USER" - }, "driver_node_type_id": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "[NODE_TYPE_ID]" }, "enable_elastic_disk": { @@ -123,7 +117,6 @@ }, "cluster_id": "[CLUSTER_ID]", "cluster_name": "test-cluster-[UNIQUE_NAME]", - "data_security_mode": "SINGLE_USER", "driver_node_type_id": "[NODE_TYPE_ID]", "enable_elastic_disk": false, "node_type_id": "[NODE_TYPE_ID]", @@ -144,20 +137,15 @@ }, "aws_attributes": { "action": "skip", - "reason": "server_side_default", + "reason": "managed", "remote": { "availability": "SPOT_WITH_FALLBACK", "zone_id": "us-east-1c" } }, - "data_security_mode": { - "action": "skip", - "reason": "server_side_default", - "remote": "SINGLE_USER" - }, "driver_node_type_id": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "[NODE_TYPE_ID]" }, "enable_elastic_disk": { @@ -201,7 +189,6 @@ }, "cluster_id": "[CLUSTER_ID]", "cluster_name": "test-cluster-[UNIQUE_NAME]", - "data_security_mode": "SINGLE_USER", "driver_node_type_id": "[NODE_TYPE_ID]", "enable_elastic_disk": false, "node_type_id": "[NODE_TYPE_ID]", @@ -225,20 +212,15 @@ }, "aws_attributes": { "action": "skip", - "reason": "server_side_default", + "reason": "managed", "remote": { "availability": "SPOT_WITH_FALLBACK", "zone_id": "us-east-1c" } }, - "data_security_mode": { - "action": "skip", - "reason": "server_side_default", - "remote": "SINGLE_USER" - }, "driver_node_type_id": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "[NODE_TYPE_ID]" }, "enable_elastic_disk": { @@ -279,7 +261,6 @@ }, "cluster_id": "[CLUSTER_ID]", "cluster_name": "test-cluster-[UNIQUE_NAME]", - "data_security_mode": "SINGLE_USER", "driver_node_type_id": "[NODE_TYPE_ID]", "enable_elastic_disk": false, "node_type_id": "[NODE_TYPE_ID]", @@ -301,20 +282,15 @@ }, "aws_attributes": { "action": "skip", - "reason": "server_side_default", + "reason": "managed", "remote": { "availability": "SPOT_WITH_FALLBACK", "zone_id": "us-east-1c" } }, - "data_security_mode": { - "action": "skip", - "reason": "server_side_default", - "remote": "SINGLE_USER" - }, "driver_node_type_id": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "[NODE_TYPE_ID]" }, "enable_elastic_disk": { diff --git a/acceptance/bundle/resources/clusters/deploy/update-and-resize-autoscale/output.txt b/acceptance/bundle/resources/clusters/deploy/update-and-resize-autoscale/output.txt index 339aa0a105..78b00d25ee 100644 --- a/acceptance/bundle/resources/clusters/deploy/update-and-resize-autoscale/output.txt +++ b/acceptance/bundle/resources/clusters/deploy/update-and-resize-autoscale/output.txt @@ -95,7 +95,6 @@ Deployment complete! }, "cluster_id":"[CLUSTER_ID]", "cluster_name":"test-cluster-[UNIQUE_NAME]", - "data_security_mode":"SINGLE_USER", "driver_node_type_id":"[NODE_TYPE_ID]", "enable_elastic_disk":false, "node_type_id":"[NODE_TYPE_ID]", diff --git a/acceptance/bundle/resources/clusters/deploy/update-and-resize/out.plan_.direct.json b/acceptance/bundle/resources/clusters/deploy/update-and-resize/out.plan_.direct.json index c96a75f91a..acf0cfa65b 100644 --- a/acceptance/bundle/resources/clusters/deploy/update-and-resize/out.plan_.direct.json +++ b/acceptance/bundle/resources/clusters/deploy/update-and-resize/out.plan_.direct.json @@ -47,7 +47,6 @@ }, "cluster_id": "[CLUSTER_ID]", "cluster_name": "test-cluster-[UNIQUE_NAME]", - "data_security_mode": "SINGLE_USER", "driver_node_type_id": "[NODE_TYPE_ID]", "enable_elastic_disk": false, "node_type_id": "[NODE_TYPE_ID]", @@ -60,20 +59,15 @@ "changes": { "aws_attributes": { "action": "skip", - "reason": "server_side_default", + "reason": "managed", "remote": { "availability": "SPOT_WITH_FALLBACK", "zone_id": "us-east-1c" } }, - "data_security_mode": { - "action": "skip", - "reason": "server_side_default", - "remote": "SINGLE_USER" - }, "driver_node_type_id": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "[NODE_TYPE_ID]" }, "enable_elastic_disk": { @@ -119,7 +113,6 @@ }, "cluster_id": "[CLUSTER_ID]", "cluster_name": "test-cluster-[UNIQUE_NAME]", - "data_security_mode": "SINGLE_USER", "driver_node_type_id": "[NODE_TYPE_ID]", "enable_elastic_disk": false, "node_type_id": "[NODE_TYPE_ID]", @@ -133,20 +126,15 @@ "changes": { "aws_attributes": { "action": "skip", - "reason": "server_side_default", + "reason": "managed", "remote": { "availability": "SPOT_WITH_FALLBACK", "zone_id": "us-east-1c" } }, - "data_security_mode": { - "action": "skip", - "reason": "server_side_default", - "remote": "SINGLE_USER" - }, "driver_node_type_id": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "[NODE_TYPE_ID]" }, "enable_elastic_disk": { @@ -193,7 +181,6 @@ }, "cluster_id": "[CLUSTER_ID]", "cluster_name": "test-cluster-[UNIQUE_NAME]", - "data_security_mode": "SINGLE_USER", "driver_node_type_id": "[NODE_TYPE_ID]", "enable_elastic_disk": false, "node_type_id": "[NODE_TYPE_ID]", @@ -207,20 +194,15 @@ "changes": { "aws_attributes": { "action": "skip", - "reason": "server_side_default", + "reason": "managed", "remote": { "availability": "SPOT_WITH_FALLBACK", "zone_id": "us-east-1c" } }, - "data_security_mode": { - "action": "skip", - "reason": "server_side_default", - "remote": "SINGLE_USER" - }, "driver_node_type_id": { "action": "skip", - "reason": "server_side_default", + "reason": "backend_default", "remote": "[NODE_TYPE_ID]" }, "enable_elastic_disk": { diff --git a/acceptance/bundle/resources/clusters/deploy/update-and-resize/output.txt b/acceptance/bundle/resources/clusters/deploy/update-and-resize/output.txt index 6460372627..43c78fa780 100644 --- a/acceptance/bundle/resources/clusters/deploy/update-and-resize/output.txt +++ b/acceptance/bundle/resources/clusters/deploy/update-and-resize/output.txt @@ -51,7 +51,6 @@ Deployment complete! }, "cluster_id":"[CLUSTER_ID]", "cluster_name":"test-cluster-[UNIQUE_NAME]", - "data_security_mode":"SINGLE_USER", "driver_node_type_id":"[NODE_TYPE_ID]", "enable_elastic_disk":false, "node_type_id":"[NODE_TYPE_ID]", From aa91788908278f7d78b9b723c2b5eb0834c7c649 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 18 Feb 2026 13:55:41 +0100 Subject: [PATCH 21/21] s/not_returned_by_api/input_only --- acceptance/bundle/migrate/runas/out.plan.json | 2 +- .../quality_monitors/change_assets_dir/out.plan.direct.json | 2 +- .../change_output_schema_name/out.plan.direct.json | 2 +- .../quality_monitors/change_table_name/out.plan.direct.json | 2 +- .../quality_monitors/create/out.plan_noop.direct.json | 2 +- bundle/direct/dresources/resources.yml | 6 +++--- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/acceptance/bundle/migrate/runas/out.plan.json b/acceptance/bundle/migrate/runas/out.plan.json index 92ab37022b..bdab0ae3bb 100644 --- a/acceptance/bundle/migrate/runas/out.plan.json +++ b/acceptance/bundle/migrate/runas/out.plan.json @@ -34,7 +34,7 @@ "changes": { "run_as": { "action": "skip", - "reason": "not_returned_by_api", + "reason": "input_only", "old": { "service_principal_name": "[UUID]" }, diff --git a/acceptance/bundle/resources/quality_monitors/change_assets_dir/out.plan.direct.json b/acceptance/bundle/resources/quality_monitors/change_assets_dir/out.plan.direct.json index bb5aa94039..2f837c11f0 100644 --- a/acceptance/bundle/resources/quality_monitors/change_assets_dir/out.plan.direct.json +++ b/acceptance/bundle/resources/quality_monitors/change_assets_dir/out.plan.direct.json @@ -38,7 +38,7 @@ }, "warehouse_id": { "action": "skip", - "reason": "not_returned_by_api", + "reason": "input_only", "old": "[TEST_DEFAULT_WAREHOUSE_ID]", "new": "[TEST_DEFAULT_WAREHOUSE_ID]" } diff --git a/acceptance/bundle/resources/quality_monitors/change_output_schema_name/out.plan.direct.json b/acceptance/bundle/resources/quality_monitors/change_output_schema_name/out.plan.direct.json index a8b5135efa..c4705197b1 100644 --- a/acceptance/bundle/resources/quality_monitors/change_output_schema_name/out.plan.direct.json +++ b/acceptance/bundle/resources/quality_monitors/change_output_schema_name/out.plan.direct.json @@ -35,7 +35,7 @@ }, "warehouse_id": { "action": "skip", - "reason": "not_returned_by_api", + "reason": "input_only", "old": "[TEST_DEFAULT_WAREHOUSE_ID]", "new": "[TEST_DEFAULT_WAREHOUSE_ID]" } diff --git a/acceptance/bundle/resources/quality_monitors/change_table_name/out.plan.direct.json b/acceptance/bundle/resources/quality_monitors/change_table_name/out.plan.direct.json index c63af6ed43..8d70f68dc7 100644 --- a/acceptance/bundle/resources/quality_monitors/change_table_name/out.plan.direct.json +++ b/acceptance/bundle/resources/quality_monitors/change_table_name/out.plan.direct.json @@ -38,7 +38,7 @@ }, "warehouse_id": { "action": "skip", - "reason": "not_returned_by_api", + "reason": "input_only", "old": "[TEST_DEFAULT_WAREHOUSE_ID]", "new": "[TEST_DEFAULT_WAREHOUSE_ID]" } diff --git a/acceptance/bundle/resources/quality_monitors/create/out.plan_noop.direct.json b/acceptance/bundle/resources/quality_monitors/create/out.plan_noop.direct.json index 729c1cf466..8805337438 100644 --- a/acceptance/bundle/resources/quality_monitors/create/out.plan_noop.direct.json +++ b/acceptance/bundle/resources/quality_monitors/create/out.plan_noop.direct.json @@ -20,7 +20,7 @@ "changes": { "warehouse_id": { "action": "skip", - "reason": "not_returned_by_api", + "reason": "input_only", "old": "[TEST_DEFAULT_WAREHOUSE_ID]", "new": "[TEST_DEFAULT_WAREHOUSE_ID]" } diff --git a/bundle/direct/dresources/resources.yml b/bundle/direct/dresources/resources.yml index 1739418a15..4eb39aeb2e 100644 --- a/bundle/direct/dresources/resources.yml +++ b/bundle/direct/dresources/resources.yml @@ -137,7 +137,7 @@ resources: - field: id reason: "!drop" - field: run_as - reason: not_returned_by_api + reason: input_only ignore_local_changes: # "id" is output-only, providing it in config would be a mistake @@ -285,11 +285,11 @@ resources: reason: immutable ignore_remote_changes: - field: warehouse_id - reason: not_returned_by_api + reason: input_only # skip_builtin_dashboard is input-only, not returned by the Get API. # TF preserves it from state; see resource_quality_monitor.go. - field: skip_builtin_dashboard - reason: not_returned_by_api + reason: input_only catalogs: recreate_on_changes: