Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
633546f
Migrate terraform state to direct before deploy instead of after
denik Sep 18, 2026
55ebd54
acceptance: regenerate migrate goldens for pre-deploy migration; chan…
denik Sep 18, 2026
47ab384
migrate: gate pre-deploy migration on plan check, fall back to terraform
denik Sep 18, 2026
ac6be33
acceptance: regenerate resource_deps goldens for pre-deploy migration
denik Sep 18, 2026
c53de39
acceptance: rework state_present for pre-deploy migration
denik Sep 18, 2026
8584072
Reuse MigrateToDirect for pre-deploy migration; drop OpenMigratedTerr…
denik Sep 18, 2026
2d6c394
Revert state_present to main pending plan-behavior decision
denik Sep 18, 2026
4068fdc
migrate: plan migrates in-memory (no commit), deploy commits; delete …
denik Sep 18, 2026
3d3089f
acceptance: regenerate migrate goldens for plan-in-memory/deploy-comm…
denik Sep 18, 2026
ef75f51
acceptance: rework state_present + regenerate resource_deps/telemetry…
denik Sep 18, 2026
12f0132
Revert state_present again; plan-path migration behavior needs invest…
denik Sep 18, 2026
e03c69a
Fix user-agent engine tag after pre-deploy migration; rework state_pr…
denik Sep 18, 2026
b880ebf
acceptance: regenerate goldens for engine user-agent fix on migration
denik Sep 18, 2026
2ab9c01
acceptance: fix auto-migrate-plan-failure fault offset
denik Sep 21, 2026
7d50b5f
Migrate all terraform-state resources; commit migration on destroy
denik Sep 21, 2026
69794f9
migration: always clean up temp state file
denik Sep 21, 2026
f723bb9
Run terraform→direct migration after phases.Build
denik Sep 21, 2026
bd4c6b0
Fall back to terraform when the migration commit fails
denik Sep 21, 2026
fdfa476
Warn when migration snapshots an unapplied resource rename
denik Sep 21, 2026
5ad08e0
Harden migration commit: deploy implies commit, safer rollback
denik Sep 21, 2026
1f35847
Merge origin/main into denik/migration-before-deploy
denik Sep 21, 2026
c674d50
Fix auto-migrate-artifacts wheel fixture; compact migration notice
denik Sep 21, 2026
20230d6
Reword auto-migration notice
denik Sep 21, 2026
0aa9bb5
Drop blank lines around the one-line migration notice
denik Sep 21, 2026
00ca741
Restore migration telemetry; migrate-test cleanups from review
denik Sep 21, 2026
da93d81
Order process.go linearly: build, migrate, open state, deploy
denik Sep 21, 2026
4d23798
Fail open on terraform cleanup instead of rolling back the migration
denik Sep 21, 2026
32d7ffe
Merge #6772 (fail-open migration cleanup); stack PR on top
denik Sep 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .nextchanges/bundles/migrate-before-deploy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Migrate existing Terraform deployment state to the direct engine before deploying (previously done after a Terraform deploy), so the deploy runs on the direct engine. ([#6749](https://github.com/databricks/cli/pull/6749))
2 changes: 2 additions & 0 deletions acceptance/bundle/deploy/snapshot-comparison/output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ Destroy: 2 deleted

=== Cleanup bundle 2
>>> [CLI] bundle destroy --auto-approve
Notice: automatically migrating your bundle to direct deployment engine (https://github.com/databricks/cli/issues/6765).
Migrated 2 resources to direct deployment engine.
The following resources will be deleted:
delete resources.jobs.test_job
delete resources.pipelines.test_pipeline
Expand Down
15 changes: 15 additions & 0 deletions acceptance/bundle/migrate/auto-migrate-artifacts/databricks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
bundle:
name: test-bundle

resources:
jobs:
test_job:
name: "Test Auto-Migrate Artifacts Job"
tasks:
- task_key: TestTask
existing_cluster_id: "0717-132531-5opeqon1"
python_wheel_task:
package_name: "my_test_code"
entry_point: "run"
libraries:
- whl: ./dist/*.whl
Binary file not shown.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions acceptance/bundle/migrate/auto-migrate-artifacts/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

=== Initial deploy on terraform (expands the whl glob and uploads the wheel)
>>> DATABRICKS_BUNDLE_ENGINE=terraform [CLI] bundle deploy
Warn: unable to get spark version for cluster 0717-132531-5opeqon1, err: Not Found
Uploading dist/my_test_code-0.0.1-py3-none-any.whl...
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
Created jobs.test_job
Files: 4 uploaded, 0 deleted
Resources: 1 created, 0 changed, 0 deleted, 0 unchanged

=== Redeploy with direct default: auto-migration runs after the build, so library refs are resolved
>>> [CLI] bundle deploy
Warn: unable to get spark version for cluster 0717-132531-5opeqon1, err: Not Found
Notice: automatically migrating your bundle to direct deployment engine (https://github.com/databricks/cli/issues/6765).
Migrated 1 resource to direct deployment engine.
Uploading dist/my_test_code-0.0.1-py3-none-any.whl...
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
Files: 0 uploaded, 0 deleted
Resources: 0 created, 0 changed, 0 deleted, 1 unchanged

=== Local state is now direct

>>> find .databricks/bundle -name resources.json -type f
.databricks/bundle/default/resources.json

>>> find .databricks/bundle -name terraform.tfstate* -type f
.databricks/bundle/default/terraform/terraform.tfstate.backup

=== Migrated state's library path (should be the resolved remote path, not the local glob)
>>> print_state.py
[
{
"whl": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/artifacts/.internal/my_test_code-0.0.1-py3-none-any.whl"
}
]

=== Subsequent deploy is a no-op on direct
>>> [CLI] bundle deploy
Warn: unable to get spark version for cluster 0717-132531-5opeqon1, err: Not Found
Uploading dist/my_test_code-0.0.1-py3-none-any.whl...
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
Files: 0 uploaded, 0 deleted
Resources: 0 created, 0 changed, 0 deleted, 1 unchanged
17 changes: 17 additions & 0 deletions acceptance/bundle/migrate/auto-migrate-artifacts/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export DATABRICKS_BUNDLE_ENGINE=

title "Initial deploy on terraform (expands the whl glob and uploads the wheel)"
trace DATABRICKS_BUNDLE_ENGINE=terraform $CLI bundle deploy

title "Redeploy with direct default: auto-migration runs after the build, so library refs are resolved"
trace $CLI bundle deploy

title "Local state is now direct\n"
trace find .databricks/bundle -name "resources.json" -type f
trace find .databricks/bundle -name "terraform.tfstate*" -type f

title "Migrated state's library path (should be the resolved remote path, not the local glob)"
trace print_state.py | jq '.. | .libraries? | select(.)'

title "Subsequent deploy is a no-op on direct"
trace $CLI bundle deploy
1 change: 1 addition & 0 deletions acceptance/bundle/migrate/auto-migrate-artifacts/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
RecordRequests = false
4 changes: 1 addition & 3 deletions acceptance/bundle/migrate/auto-migrate-clean/output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ direct_drymigrate_warnings false
engine: direct

>>> [CLI] bundle deploy
Warn: Direct engine selected via bundle.engine setting at [TEST_TMP_DIR]/databricks.yml:3:11 but the existing state uses "terraform". Deploying on "terraform"; will attempt to migrate the state to the direct engine after this deploy.
Migrated 1 resource to direct deployment engine.
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
Files: 1 uploaded, 0 deleted
Resources: 0 created, 0 changed, 0 deleted, 1 unchanged
Migrating state to direct deployment engine (selected via bundle.engine setting at [TEST_TMP_DIR]/databricks.yml:3:11)...
Migrated 1 resource to direct deployment engine.

>>> print_migration_telemetry
direct_migrated_via_config true
Expand Down
10 changes: 2 additions & 8 deletions acceptance/bundle/migrate/auto-migrate-default/output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,11 @@ direct_drymigrate_warnings false

=== Redeploy with nothing set: direct is the default, so auto-migration triggers
>>> [CLI] bundle deploy
Notice: the direct deployment engine is the default as of CLI v1.14.0.

This bundle will be automatically migrated to use the direct deployment engine after this deployment.

Learn more: https://docs.databricks.com/dev-tools/bundles/direct

Notice: automatically migrating your bundle to direct deployment engine (https://github.com/databricks/cli/issues/6765).
Migrated 1 resource to direct deployment engine.
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
Files: 0 uploaded, 0 deleted
Resources: 0 created, 0 changed, 0 deleted, 1 unchanged
Migrating state to direct deployment engine (selected via default)...
Migrated 1 resource to direct deployment engine.

>>> print_migration_telemetry
direct_migrated_via_default true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
bundle:
name: test-bundle

resources:
jobs:
job_a:
name: "Job A"

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions acceptance/bundle/migrate/auto-migrate-delete-all/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

=== Initial deploy on terraform
>>> DATABRICKS_BUNDLE_ENGINE=terraform [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
Created jobs.job_a
Files: 3 uploaded, 0 deleted
Resources: 1 created, 0 changed, 0 deleted, 0 unchanged

=== Remove all resources, then deploy on direct: migrate and delete
>>> [CLI] bundle deploy
Notice: automatically migrating your bundle to direct deployment engine (https://github.com/databricks/cli/issues/6765).
Migrated 1 resource to direct deployment engine.
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
Deleted jobs.job_a
Files: 1 uploaded, 0 deleted
Resources: 0 created, 0 changed, 1 deleted, 0 unchanged

=== Follow-up plan is a clean no-op
>>> [CLI] bundle plan
Plan: 0 to add, 0 to change, 0 to delete, 0 unchanged
15 changes: 15 additions & 0 deletions acceptance/bundle/migrate/auto-migrate-delete-all/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export DATABRICKS_BUNDLE_ENGINE=

title "Initial deploy on terraform"
trace DATABRICKS_BUNDLE_ENGINE=terraform $CLI bundle deploy

# Removing every resource leaves the migration with no config-declared resources, so
# BuildStateFromTF records no WAL entries. The migration must still persist the seeded
# terraform-state resources so the direct plan can delete them (otherwise Finalize would
# write no state file and the migration would fail with a missing resources.json).
title "Remove all resources, then deploy on direct: migrate and delete"
echo '{"bundle": {"name": "test-bundle"}}' > databricks.yml
trace $CLI bundle deploy

title "Follow-up plan is a clean no-op"
trace $CLI bundle plan | contains.py "0 to delete, 0 unchanged"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
RecordRequests = false
9 changes: 9 additions & 0 deletions acceptance/bundle/migrate/auto-migrate-delete/databricks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
bundle:
name: test-bundle

resources:
jobs:
job_keep:
name: "Keep Job"
job_drop: # TO_REMOVE
name: "Drop Job" # TO_REMOVE
3 changes: 3 additions & 0 deletions acceptance/bundle/migrate/auto-migrate-delete/out.test.toml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions acceptance/bundle/migrate/auto-migrate-delete/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

=== Initial deploy on terraform with two jobs
>>> DATABRICKS_BUNDLE_ENGINE=terraform [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
Created jobs.job_drop
Created jobs.job_keep
Files: 3 uploaded, 0 deleted
Resources: 2 created, 0 changed, 0 deleted, 0 unchanged

=== Drop one job from config, then deploy on direct: migrate two, delete the dropped one
>>> [CLI] bundle deploy
Notice: automatically migrating your bundle to direct deployment engine (https://github.com/databricks/cli/issues/6765).
Migrated 2 resources to direct deployment engine.
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
Deleted jobs.job_drop
Files: 1 uploaded, 0 deleted
Resources: 0 created, 0 changed, 1 deleted, 1 unchanged

=== Follow-up plan is a clean no-op
>>> [CLI] bundle plan
Plan: 0 to add, 0 to change, 0 to delete, 1 unchanged
13 changes: 13 additions & 0 deletions acceptance/bundle/migrate/auto-migrate-delete/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export DATABRICKS_BUNDLE_ENGINE=

title "Initial deploy on terraform with two jobs"
trace DATABRICKS_BUNDLE_ENGINE=terraform $CLI bundle deploy

# The migration seeds every terraform-state resource into the direct state, so the
# first direct plan can delete the ones the config no longer declares.
title "Drop one job from config, then deploy on direct: migrate two, delete the dropped one"
grep -v 'TO_REMOVE' databricks.yml > updated.yml && mv updated.yml databricks.yml
trace $CLI bundle deploy

title "Follow-up plan is a clean no-op"
trace $CLI bundle plan | contains.py "1 unchanged"
1 change: 1 addition & 0 deletions acceptance/bundle/migrate/auto-migrate-delete/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
RecordRequests = false
7 changes: 7 additions & 0 deletions acceptance/bundle/migrate/auto-migrate-destroy/databricks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
bundle:
name: test-bundle

resources:
jobs:
job_a:
name: "Job A"
3 changes: 3 additions & 0 deletions acceptance/bundle/migrate/auto-migrate-destroy/out.test.toml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions acceptance/bundle/migrate/auto-migrate-destroy/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

=== Initial deploy on terraform
>>> DATABRICKS_BUNDLE_ENGINE=terraform [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
Created jobs.job_a
Files: 3 uploaded, 0 deleted
Resources: 1 created, 0 changed, 0 deleted, 0 unchanged

=== Destroy on direct: migrate (commit) then destroy
>>> [CLI] bundle destroy --auto-approve
Notice: automatically migrating your bundle to direct deployment engine (https://github.com/databricks/cli/issues/6765).
Migrated 1 resource to direct deployment engine.
The following resources will be deleted:
delete resources.jobs.job_a

All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default

Destroy: 1 deleted

=== resources.json removed by destroy; terraform state backed up
>>> find .databricks/bundle -name resources.json -type f

>>> find .databricks/bundle -name terraform.tfstate* -type f
.databricks/bundle/default/terraform/terraform.tfstate.backup
14 changes: 14 additions & 0 deletions acceptance/bundle/migrate/auto-migrate-destroy/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export DATABRICKS_BUNDLE_ENGINE=

title "Initial deploy on terraform"
trace DATABRICKS_BUNDLE_ENGINE=terraform $CLI bundle deploy

# Destroy behaves like deploy: it migrates the terraform state to direct in memory,
# plan-checks it, commits the migration (resources.json pushed, terraform.tfstate backed
# up), then destroys on the direct engine.
title "Destroy on direct: migrate (commit) then destroy"
trace $CLI bundle destroy --auto-approve

title "resources.json removed by destroy; terraform state backed up"
trace find .databricks/bundle -name "resources.json" -type f
trace find .databricks/bundle -name "terraform.tfstate*" -type f
1 change: 1 addition & 0 deletions acceptance/bundle/migrate/auto-migrate-destroy/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
RecordRequests = false
Original file line number Diff line number Diff line change
Expand Up @@ -9,45 +9,27 @@ Resources: 1 created, 0 changed, 0 deleted, 0 unchanged
=== Add a direct-only resource to the config
>>> update_file.py databricks.yml #instance_pools instance_pools

=== Opt in via env var only: deploy migrates the state, ignoring the direct-only resource
=== Opt in via env var only: deploy migrates the state and creates the direct-only resource
>>> DATABRICKS_BUNDLE_ENGINE=direct [CLI] bundle deploy
Warn: Direct engine selected via DATABRICKS_BUNDLE_ENGINE environment variable but the existing state uses "terraform". Deploying on "terraform"; will attempt to migrate the state to the direct engine after this deploy.
Migrated 1 resource to direct deployment engine.
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
Created instance_pools.pool
Files: 1 uploaded, 0 deleted
Resources: 0 created, 0 changed, 0 deleted, 2 unchanged
Migrating state to direct deployment engine (selected via DATABRICKS_BUNDLE_ENGINE environment variable)...
Migrated 1 resource to direct deployment engine.
Resources: 1 created, 0 changed, 0 deleted, 1 unchanged

>>> print_migration_telemetry
direct_migrated_via_env true

=== The direct-only resource is created on the next deploy
=== Redeploy is a no-op: state is already on the direct engine
>>> [CLI] bundle plan
create instance_pools.pool

Plan: 1 to add, 0 to change, 0 to delete, 1 unchanged
Plan: 0 to add, 0 to change, 0 to delete, 2 unchanged

>>> [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
Created instance_pools.pool
Files: 0 uploaded, 0 deleted
Resources: 1 created, 0 changed, 0 deleted, 1 unchanged
Resources: 0 created, 0 changed, 0 deleted, 2 unchanged

>>> print_requests.py //instance-pools/create
{
"headers": {
"User-Agent": [
"cli/[CLI_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_deploy cmd-exec-id/[UUID] interactive/none engine/direct auth/pat"
]
},
"method": "POST",
"path": "/api/2.0/instance-pools/create",
"body": {
"idle_instance_autotermination_minutes": 60,
"instance_pool_name": "My Pool",
"node_type_id": "Standard_DS3_v2"
}
}

=== No further actions planned
>>> [CLI] bundle plan
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ rm -f "$OUT_REQUESTS"
title "Add a direct-only resource to the config"
trace update_file.py databricks.yml "#instance_pools" "instance_pools"

title "Opt in via env var only: deploy migrates the state, ignoring the direct-only resource"
title "Opt in via env var only: deploy migrates the state and creates the direct-only resource"
trace DATABRICKS_BUNDLE_ENGINE=direct $CLI bundle deploy
trace print_migration_telemetry
rm -f "$OUT_REQUESTS"

title "The direct-only resource is created on the next deploy"
title "Redeploy is a no-op: state is already on the direct engine"
trace $CLI bundle plan
trace $CLI bundle deploy
trace print_requests.py //instance-pools/create
Expand Down
Loading
Loading