Skip to content

Fix secret scope permissions migration from Terraform to Direct engine #4866

Open
denik wants to merge 21 commits intomainfrom
denik/fix-secrets-migration
Open

Fix secret scope permissions migration from Terraform to Direct engine #4866
denik wants to merge 21 commits intomainfrom
denik/fix-secrets-migration

Conversation

@denik
Copy link
Copy Markdown
Contributor

@denik denik commented Mar 30, 2026

Summary

  • Fix bundle deployment migrate for bundles with secret scopes to prevent phantom drift on secret_scopes.*.permissions after migration from Terraform to Direct engine.
  • Handle databricks_secret_acl in ParseResourcesState: multiple ACL resources per scope are mapped to a single .permissions state entry with the scope name as ID, similar to how databricks_permissions and databricks_grants are handled.
  • Expose resources.secret_scopes.foo.permissions as a separate entry in terraform JSON plan as well to match direct engine.

Test plan

  • Re-enable the previously excluded secret scope migration acceptance tests.
  • New invariant test config for secret scope with ACLs.

@denik denik temporarily deployed to test-trigger-is March 30, 2026 09:06 — with GitHub Actions Inactive
@eng-dev-ecosystem-bot
Copy link
Copy Markdown
Collaborator

eng-dev-ecosystem-bot commented Mar 30, 2026

Commit: 2a198db

Run: 23806620592

Env 🟨​KNOWN 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
🟨​ aws linux 7 10 270 810 7:49
🟨​ aws windows 7 10 272 808 7:16
💚​ aws-ucws linux 7 10 366 726 7:12
💚​ aws-ucws windows 7 10 368 724 6:22
💚​ azure linux 1 12 273 808 6:05
💚​ azure windows 1 12 275 806 5:36
💚​ azure-ucws linux 1 12 371 722 8:33
🔄​ azure-ucws windows 3 12 371 720 6:32
💚​ gcp linux 1 12 269 811 6:10
💚​ gcp windows 1 12 271 809 6:49
19 interesting tests: 10 SKIP, 7 KNOWN, 2 flaky
Test Name aws linux aws windows aws-ucws linux aws-ucws windows azure linux azure windows azure-ucws linux azure-ucws windows gcp linux gcp windows
🟨​ TestAccept 🟨​K 🟨​K 💚​R 💚​R 💚​R 💚​R 💚​R 🔄​f 💚​R 💚​R
🔄​ TestAccept/bundle/resources/model_serving_endpoints/basic 🙈​s 🙈​s ✅​p ✅​p 🙈​s 🙈​s ✅​p 🔄​f 🙈​s 🙈​s
🔄​ TestAccept/bundle/resources/model_serving_endpoints/basic/DATABRICKS_BUNDLE_ENGINE=direct ✅​p ✅​p ✅​p 🔄​f
🙈​ TestAccept/bundle/resources/permissions 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions 🟨​K 🟨​K 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=direct 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions 🟨​K 🟨​K 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=direct 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 🟨​K 🟨​K 💚​R 💚​R
🙈​ TestAccept/bundle/resources/postgres_branches/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/recreate 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/update_protected 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/without_branch_id 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_endpoints/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_endpoints/recreate 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_projects/update_display_name 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/synced_database_tables/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/ssh/connection 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
Top 20 slowest tests (at least 2 minutes):
duration env testname
4:13 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:50 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:45 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:44 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:42 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:26 azure linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:21 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:20 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:20 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:17 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:13 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:55 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:48 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:42 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:41 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:41 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:38 azure linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:17 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:15 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:05 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct

@denik denik force-pushed the denik/fix-secrets-migration branch from 1f437ff to 9434908 Compare March 31, 2026 11:04
@denik denik temporarily deployed to test-trigger-is March 31, 2026 11:04 — with GitHub Actions Inactive
@denik denik force-pushed the denik/fix-secrets-migration branch from 9434908 to 2a198db Compare March 31, 2026 15:51
@denik denik temporarily deployed to test-trigger-is March 31, 2026 15:52 — with GitHub Actions Inactive
@denik denik had a problem deploying to test-trigger-is April 1, 2026 06:52 — with GitHub Actions Failure
@denik denik marked this pull request as ready for review April 1, 2026 06:57
@denik denik enabled auto-merge April 1, 2026 06:58
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 1, 2026

Suggested reviewers

Based on git history of the changed files, these people are best suited to review:

  • @pietern -- recent work in bundle/deploy/terraform/, cmd/bundle/deployment/, acceptance/bundle/invariant/

Confidence: high

Eligible reviewers

Based on CODEOWNERS, these people or teams could also review:

@andrewnester, @anton-107, @shreyas-goenka, @simonfaltum

Suggestions based on git history of 20 changed files (9 scored). See CODEOWNERS for path-specific ownership rules.

@denik denik had a problem deploying to test-trigger-is April 1, 2026 06:58 — with GitHub Actions Failure
denik added 13 commits April 1, 2026 09:00
During migration, Terraform's databricks_secret_acl resources are not
tracked in the migration state. The direct engine manages secret scope
permissions as a sub-resource (secret_scopes.*.permissions), so without
a state entry, the post-migration plan shows a "create" action.

Add state entries for secret_scopes.*.permissions after migration Apply
to prevent phantom drift.

Co-authored-by: Isaac
Add databricks_secret_acl to TerraformToGroupName mapping and handle it
in parseResourcesState, similar to how databricks_permissions and
databricks_grants are handled. Multiple ACL resources per scope map to a
single .permissions entry with the scope name as ID.

Co-authored-by: Isaac
…rcesState

ParseResourcesState now creates .permissions entries for ALL secret scopes
(not just those with databricks_secret_acl), so the post-Apply fixup in
migrate.go is no longer needed.

Co-authored-by: Isaac
Add a test config with a secret scope that has two explicit ACL
permissions (READ for users, WRITE for account users). This exercises
the multi-ACL migration path in parseResourcesState.

Co-authored-by: Isaac
During migration, SecretScopeFixups wasn't running (it's part of
PreDeployChecks which migration skips). For scopes without explicit ACLs,
parseResourcesState synthesizes .permissions entries in the state, but
the config didn't have them, causing a Delete→forced Update→no StateCache
entry error chain.

Fix: apply SecretScopeFixups(EngineDirect) before CalculatePlan so the
config and state agree on .permissions entries.

Also simplify the identical if/else branches in the safety net.

Co-authored-by: Isaac
The 'account users' group doesn't exist on all test workspaces,
causing cloud test failures.

Co-authored-by: Isaac
The convertSecretAclResourceNameToKey function and its dedicated
databricks_secret_acl branch in parseResourcesState are no longer
needed — all secret scope permissions are now handled uniformly
through the post-processing loop.

Co-authored-by: Isaac
Add SecretScopeFixups(EngineDirect) before reading b.Config.Value()
so the config includes .permissions entries for secret scopes. Without
this, CalculatePlan sees .permissions in state but not in config and
produces incorrect plan entries during YAML sync conversion.

Co-authored-by: Isaac
Check silentlyUpdatedResources before logging unknown resource type warning,
matching the pattern used in showplanfile.go. This prevents misleading
"Unknown Terraform resource type: databricks_secret_acl" warnings during
normal secret scope migrations.

Co-authored-by: Isaac
Replace the single-entry map with a direct type check for
databricks_secret_acl in both showplanfile.go and util.go.

Co-authored-by: Isaac
Add "secret_acls" mapping for databricks_secret_acl instead of
special-casing it in the unknown-type check. In parseResourcesState,
secret_acls are skipped via the switch (post-processing creates
.permissions entries). In populatePlan, secret ACL changes are mapped
to resources.secret_scopes.<key>.permissions with GetHigherAction
for merging multiple ACL changes per scope.

Task: 017.md

Co-authored-by: Isaac
denik added 5 commits April 1, 2026 09:00
Secret ACL changes now appear as .permissions entries in the Terraform
plan output, reflecting the new TerraformToGroupName mapping.

Task: 017.md

Co-authored-by: Isaac
Instead of a post-processing loop that adds .permissions for every
secret scope, create the entry directly in the "secret_scopes" case.
This keeps all resource types handled inside the switch.

Task: 018.md
When multiple secret ACL changes for the same scope include both creates
and deletes, report the net action as "update" instead of "delete".
GetHigherAction picks the highest severity (delete > create), but mixed
ACL changes represent a permissions update, not a deletion.

Task: 019.md

Co-authored-by: Isaac
The previous isCreateDeleteMix helper only handled the narrow case of
separate Create and Delete actions. In practice, Terraform produces
Recreate (delete+create pair) for ACLs with changed principals, mixed
with Delete for removed principals. GetHigherAction(Recreate, Delete)
returned Delete (severity 7>6), incorrectly reporting permissions as
deleted rather than updated.

Simplify the logic: for secret ACLs, any mix of different action types
means permissions are being updated. Only same-action merges (e.g., all
Recreate when scope is recreated) keep the original action.

Task-review: /Users/denis.bilenko/work/prompts/features/fix-secrets-migration/021.SUMMARY.md

Co-authored-by: Isaac
@denik denik force-pushed the denik/fix-secrets-migration branch from a3675b6 to b7abfb4 Compare April 1, 2026 07:00
@denik denik had a problem deploying to test-trigger-is April 1, 2026 07:00 — with GitHub Actions Failure
@denik denik had a problem deploying to test-trigger-is April 1, 2026 08:56 — with GitHub Actions Failure
@denik denik had a problem deploying to test-trigger-is April 1, 2026 10:51 — with GitHub Actions Failure
@denik denik disabled auto-merge April 1, 2026 13:30
@denik denik force-pushed the denik/fix-secrets-migration branch from 6a02590 to c8f3b0e Compare April 1, 2026 14:23
@denik denik had a problem deploying to test-trigger-is April 1, 2026 14:23 — with GitHub Actions Failure
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants