Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
292eac2
add cluster policy basics to repo
Sankalp-Mittal Aug 11, 2026
577efbf
fix double quotes
Sankalp-Mittal Aug 11, 2026
44b2393
add CRUD policies
Sankalp-Mittal Aug 11, 2026
f5a668f
register cluster policies in all.go
Sankalp-Mittal Aug 11, 2026
bc3de96
add cluster policies to the testserver
Sankalp-Mittal Aug 11, 2026
2202fd0
fix syntax error
Sankalp-Mittal Aug 11, 2026
d0aeb0e
add generated bundle files
Sankalp-Mittal Aug 11, 2026
368fbb8
add acceptance tests for cluster policies
Sankalp-Mittal Aug 11, 2026
ddd5bdb
add cluster_policies to mutator
Sankalp-Mittal Aug 11, 2026
8bcb462
add URL to for policy to output
Sankalp-Mittal Aug 11, 2026
cd13a39
fix tests
Sankalp-Mittal Aug 11, 2026
61405c8
make cluster policies direct deployments only
Sankalp-Mittal Aug 11, 2026
77de13b
add cluster policy test everywhere
Sankalp-Mittal Aug 11, 2026
e9c9eb4
Add bind tests
Sankalp-Mittal Aug 11, 2026
896f47e
fix linting
Sankalp-Mittal Aug 11, 2026
1c6ae4d
add changelog
Sankalp-Mittal Aug 11, 2026
01928b4
regenerate schema files for cluster_policies
Sankalp-Mittal Aug 11, 2026
46bcd67
fix workspace_open tests for cluster_policies resource type
Sankalp-Mittal Aug 11, 2026
ee55a15
update experimental/open acceptance golden for cluster_policies
Sankalp-Mittal Aug 11, 2026
98576cd
add cluster_policies invariant test coverage
Sankalp-Mittal Aug 11, 2026
3aac44d
test: expand cluster_policies acceptance coverage
Sankalp-Mittal Aug 13, 2026
ffdd6df
Support authoring cluster_policies definition as inline YAML
Sankalp-Mittal Aug 13, 2026
43698b5
test: cover cluster_policies inline-YAML definition
Sankalp-Mittal Aug 13, 2026
671f0e2
regenerate refschema for cluster_policies inline-YAML definition
Sankalp-Mittal Aug 13, 2026
e5280fd
test: cluster_policies rejected in terraform mode
Sankalp-Mittal Aug 13, 2026
be7ccb2
test: cluster_policies dangling reference fails to plan
Sankalp-Mittal Aug 13, 2026
e9aa452
test: cross-bundle cluster_policy use via hardcoded id
Sankalp-Mittal Aug 13, 2026
60ede9e
test: cross-bundle cluster_policy use via lookup by name
Sankalp-Mittal Aug 13, 2026
780cbb8
test: vary cluster_policies definition authoring across fixtures
Sankalp-Mittal Aug 13, 2026
2df7f3c
add a test for an out of band change
Sankalp-Mittal Aug 17, 2026
bfacfa3
add non string field to yaml
Sankalp-Mittal Aug 17, 2026
d9f0ca0
delete tests not specific to cluster policies
Sankalp-Mittal Aug 17, 2026
aef7b32
add policy_family_definition_overrides support
Sankalp-Mittal Aug 17, 2026
4330dde
regenerate file
Sankalp-Mittal Aug 17, 2026
71f4f5e
delete cross bundle tests
Sankalp-Mittal Aug 17, 2026
dc91553
update goldens for direct deployments
Sankalp-Mittal Aug 17, 2026
082450e
check for backend normalization
Sankalp-Mittal Aug 18, 2026
4a20bf5
update tests to run on cloud
Sankalp-Mittal Aug 18, 2026
4f467bf
use print_requests.py instead of inline jq in cluster_policy tests
Sankalp-Mittal Aug 18, 2026
f9e5526
add backend_defaults because of policy_family_definition_overrides
Sankalp-Mittal Aug 19, 2026
f968569
update tests to use default cloud=true
Sankalp-Mittal Aug 24, 2026
53ccee4
add test for define both
Sankalp-Mittal Aug 24, 2026
c1da779
use UNIQUE_NAME in cluster_policy cloud tests to avoid name collisions
Sankalp-Mittal Aug 24, 2026
3cc0cb9
add trailing newline to cluster_policy test scripts
Sankalp-Mittal Aug 24, 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/cluster-policies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for the `cluster_policies` resource type in Declarative Automation Bundles. Cluster policies are only supported in direct deployment mode.
8 changes: 8 additions & 0 deletions acceptance/bundle/invariant/configs/cluster_policy.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
cluster_policies:
foo:
name: test-cluster-policy-$UNIQUE_NAME
definition: '{"spark_version":{"type":"fixed","value":"13.3.x-scala2.12"}}'
3 changes: 3 additions & 0 deletions acceptance/bundle/invariant/continue_293/test.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ EnvMatrixExclude.no_genie_space = ["INPUT_CONFIG=genie_space.yml.tmpl"]
# instance_pools resource is not supported on v0.293.0
EnvMatrixExclude.no_instance_pool = ["INPUT_CONFIG=instance_pool.yml.tmpl"]

# cluster_policies resource is not supported on v0.293.0
EnvMatrixExclude.no_cluster_policy = ["INPUT_CONFIG=cluster_policy.yml.tmpl"]

# job_runs resource is not supported on v0.293.0
EnvMatrixExclude.no_job_run = ["INPUT_CONFIG=job_run.yml.tmpl"]

Expand Down

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

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

2 changes: 2 additions & 0 deletions acceptance/bundle/invariant/migrate/test.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ EnvMatrixExclude.no_external_location = ["INPUT_CONFIG=external_location.yml.tmp
EnvMatrixExclude.no_genie_space = ["INPUT_CONFIG=genie_space.yml.tmpl"]
# Instance pools are direct-only; the terraform deploy that seeds the migration fails for them.
EnvMatrixExclude.no_instance_pool = ["INPUT_CONFIG=instance_pool.yml.tmpl"]
# Cluster policies are direct-only; the terraform deploy that seeds the migration fails for them.
EnvMatrixExclude.no_cluster_policy = ["INPUT_CONFIG=cluster_policy.yml.tmpl"]

# Cross-resource permission references (e.g. ${resources.jobs.job_b.permissions[0].level})
# don't work in terraform mode: the terraform interpolator converts the path to
Expand Down
1 change: 1 addition & 0 deletions acceptance/bundle/invariant/no_drift/out.test.toml

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

1 change: 1 addition & 0 deletions acceptance/bundle/invariant/test.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ EnvMatrix.INPUT_CONFIG = [
"catalog_optional_fields.yml.tmpl",
"cluster.yml.tmpl",
"cluster_apply_policy_default_values.yml.tmpl",
"cluster_policy.yml.tmpl",
"dashboard.yml.tmpl",
"job_apply_policy_default_values_job_cluster.yml.tmpl",
"job_apply_policy_default_values_task_cluster.yml.tmpl",
Expand Down
34 changes: 34 additions & 0 deletions acceptance/bundle/refschema/out.fields.txt
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,40 @@ resources.catalogs.*.grants[*] catalog.PrivilegeAssignment ALL
resources.catalogs.*.grants[*].principal string ALL
resources.catalogs.*.grants[*].privileges []catalog.Privilege ALL
resources.catalogs.*.grants[*].privileges[*] catalog.Privilege ALL
resources.cluster_policies.*.created_at_timestamp int64 REMOTE
resources.cluster_policies.*.creator_user_name string REMOTE
resources.cluster_policies.*.definition any INPUT
resources.cluster_policies.*.definition string ALL
resources.cluster_policies.*.description string ALL
resources.cluster_policies.*.id string INPUT
resources.cluster_policies.*.is_default bool REMOTE
resources.cluster_policies.*.libraries []compute.Library ALL
resources.cluster_policies.*.libraries[*] compute.Library ALL
resources.cluster_policies.*.libraries[*].cran *compute.RCranLibrary ALL
resources.cluster_policies.*.libraries[*].cran.package string ALL
resources.cluster_policies.*.libraries[*].cran.repo string ALL
resources.cluster_policies.*.libraries[*].egg string ALL
resources.cluster_policies.*.libraries[*].jar string ALL
resources.cluster_policies.*.libraries[*].maven *compute.MavenLibrary ALL
resources.cluster_policies.*.libraries[*].maven.coordinates string ALL
resources.cluster_policies.*.libraries[*].maven.exclusions []string ALL
resources.cluster_policies.*.libraries[*].maven.exclusions[*] string ALL
resources.cluster_policies.*.libraries[*].maven.repo string ALL
resources.cluster_policies.*.libraries[*].pypi *compute.PythonPyPiLibrary ALL
resources.cluster_policies.*.libraries[*].pypi.package string ALL
resources.cluster_policies.*.libraries[*].pypi.repo string ALL
resources.cluster_policies.*.libraries[*].requirements string ALL
resources.cluster_policies.*.libraries[*].whl string ALL
resources.cluster_policies.*.lifecycle resources.Lifecycle INPUT
resources.cluster_policies.*.lifecycle.prevent_destroy bool INPUT
resources.cluster_policies.*.max_clusters_per_user int64 ALL
resources.cluster_policies.*.modified_status string INPUT
resources.cluster_policies.*.name string ALL
resources.cluster_policies.*.policy_family_definition_overrides any INPUT
resources.cluster_policies.*.policy_family_definition_overrides string ALL
resources.cluster_policies.*.policy_family_id string ALL
resources.cluster_policies.*.policy_id string REMOTE
resources.cluster_policies.*.url string INPUT
resources.clusters.*.apply_policy_default_values bool ALL
resources.clusters.*.autoscale *compute.AutoScale ALL
resources.clusters.*.autoscale.max_workers int ALL
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
bundle:
name: cluster_policy_backend_normalization

workspace:
root_path: ~/.bundle/$UNIQUE_NAME

resources:
cluster_policies:
# Definition as a compact JSON string.
json_string:
name: probe_json_string-$UNIQUE_NAME
definition: '{"spark_version":{"type":"fixed","value":"13.3.x-scala2.12"}}'

# Definition as a multiline block-scalar JSON string.
multiline:
name: probe_multiline-$UNIQUE_NAME
definition: |-
{
"spark_version": {
"type": "fixed",
"value": "13.3.x-scala2.12"
}
}

# Definition as native YAML (normalized to compact JSON by the mutator before deploy).
yaml:
name: probe_yaml-$UNIQUE_NAME
definition:
spark_version:
type: fixed
value: 13.3.x-scala2.12
autotermination_minutes:
type: range
maxValue: 120

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

>>> [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/[UNIQUE_NAME]/files...
Created cluster_policies.json_string
Created cluster_policies.multiline
Created cluster_policies.yaml
Files: 5 uploaded, 0 deleted
Resources: 3 created, 0 changed, 0 deleted, 0 unchanged

=== [json_string] definition returned by the backend (GET)
>>> [CLI] cluster-policies get [JSON_STRING_ID] -o json
{"spark_version":{"type":"fixed","value":"13.3.x-scala2.12"}}

=== [multiline] definition returned by the backend (GET)
>>> [CLI] cluster-policies get [MULTILINE_ID] -o json
{
"spark_version": {
"type": "fixed",
"value": "13.3.x-scala2.12"
}
}

=== [yaml] definition returned by the backend (GET)
>>> [CLI] cluster-policies get [YAML_ID] -o json
{"autotermination_minutes":{"maxValue":120,"type":"range"},"spark_version":{"type":"fixed","value":"13.3.x-scala2.12"}}

=== Plan after deploy: any drift means the backend reformatted a definition
>>> [CLI] bundle plan
Plan: 0 to add, 0 to change, 0 to delete, 3 unchanged

>>> [CLI] bundle destroy --auto-approve
The following resources will be deleted:
delete resources.cluster_policies.json_string
delete resources.cluster_policies.multiline
delete resources.cluster_policies.yaml

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

Destroy: 3 deleted
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
envsubst < databricks.yml.tmpl > databricks.yml

cleanup() {
trace $CLI bundle destroy --auto-approve
}
trap cleanup EXIT

trace $CLI bundle deploy

# For each authoring style, print the definition string the backend returns on GET.
# Compare it against what we sent to see whether the backend reformats the JSON.
for name in json_string multiline yaml; do
pol_id=$(read_id.py "$name")
title "[$name] definition returned by the backend (GET)"
trace $CLI cluster-policies get "$pol_id" -o json | jq -r '.definition'
done

# yaml is normalized to compact JSON by the mutator, matching the string the backend
# stores and returns, so it does not drift (plan below is a no-op).
title "Plan after deploy: any drift means the backend reformatted a definition"
trace $CLI bundle plan
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
RecordRequests = false
EnvMatrix.DATABRICKS_BUNDLE_ENGINE = ["direct"]
Ignore = [
".databricks",
"databricks.yml",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
bundle:
name: test_cluster_policy

workspace:
root_path: ~/.bundle/$UNIQUE_NAME

resources:
cluster_policies:
test_cluster_policy:
name: my_cluster_policy-$UNIQUE_NAME
definition: '{"spark_version":{"type":"fixed","value":"13.3.x-scala2.12"}}'

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

125 changes: 125 additions & 0 deletions acceptance/bundle/resources/cluster_policies/basic/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@

>>> [CLI] bundle validate
Name: test_cluster_policy
Target: default
Workspace:
User: [USERNAME]
Path: /Workspace/Users/[USERNAME]/.bundle/[UNIQUE_NAME]

Validation OK!

>>> [CLI] bundle validate -o json
{
"test_cluster_policy": {
"definition": "{\"spark_version\":{\"type\":\"fixed\",\"value\":\"13.3.x-scala2.12\"}}",
"name": "my_cluster_policy-[UNIQUE_NAME]"
}
}

>>> [CLI] bundle summary
Name: test_cluster_policy
Target: default
Workspace:
User: [USERNAME]
Path: /Workspace/Users/[USERNAME]/.bundle/[UNIQUE_NAME]
Resources:
Cluster Policies:
test_cluster_policy:
Name: my_cluster_policy-[UNIQUE_NAME]
URL: (not deployed)

>>> [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/[UNIQUE_NAME]/files...
Created cluster_policies.test_cluster_policy
Files: 5 uploaded, 0 deleted
Resources: 1 created, 0 changed, 0 deleted, 0 unchanged

=== Verify the create request
>>> print_requests.py //policies/clusters/create
{
"method": "POST",
"path": "/api/2.0/policies/clusters/create",
"body": {
"definition": "{\"spark_version\":{\"type\":\"fixed\",\"value\":\"13.3.x-scala2.12\"}}",
"name": "my_cluster_policy-[UNIQUE_NAME]"
}
}

>>> [CLI] bundle summary
Name: test_cluster_policy
Target: default
Workspace:
User: [USERNAME]
Path: /Workspace/Users/[USERNAME]/.bundle/[UNIQUE_NAME]
Resources:
Cluster Policies:
test_cluster_policy:
Name: my_cluster_policy-[UNIQUE_NAME]
URL: [DATABRICKS_URL]/compute/policies/[TEST_CLUSTER_POLICY_ID]?w=[NUMID]

=== Update the cluster policy name
>>> update_file.py databricks.yml my_cluster_policy my_cluster_policy_2

>>> [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/[UNIQUE_NAME]/files...
Updated cluster_policies.test_cluster_policy
Files: 3 uploaded, 0 deleted
Resources: 0 created, 1 changed, 0 deleted, 0 unchanged

=== Verify the update request
>>> print_requests.py //policies/clusters/edit
{
"method": "POST",
"path": "/api/2.0/policies/clusters/edit",
"body": {
"definition": "{\"spark_version\":{\"type\":\"fixed\",\"value\":\"13.3.x-scala2.12\"}}",
"name": "my_cluster_policy_2-[UNIQUE_NAME]",
"policy_id": "[TEST_CLUSTER_POLICY_ID]"
}
}

>>> [CLI] bundle summary
Name: test_cluster_policy
Target: default
Workspace:
User: [USERNAME]
Path: /Workspace/Users/[USERNAME]/.bundle/[UNIQUE_NAME]
Resources:
Cluster Policies:
test_cluster_policy:
Name: my_cluster_policy_2-[UNIQUE_NAME]
URL: [DATABRICKS_URL]/compute/policies/[TEST_CLUSTER_POLICY_ID]?w=[NUMID]

=== Destroy the cluster policy
>>> [CLI] bundle destroy --auto-approve
The following resources will be deleted:
delete resources.cluster_policies.test_cluster_policy

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

Destroy: 1 deleted

=== Verify the destroy request
>>> print_requests.py //policies/clusters/delete
{
"method": "POST",
"path": "/api/2.0/policies/clusters/delete",
"body": {
"policy_id": "[TEST_CLUSTER_POLICY_ID]"
}
}

>>> [CLI] bundle summary
Name: test_cluster_policy
Target: default
Workspace:
User: [USERNAME]
Path: /Workspace/Users/[USERNAME]/.bundle/[UNIQUE_NAME]
Resources:
Cluster Policies:
test_cluster_policy:
Name: my_cluster_policy_2-[UNIQUE_NAME]
URL: (not deployed)

>>> [CLI] bundle destroy --auto-approve
No active deployment found to destroy!
39 changes: 39 additions & 0 deletions acceptance/bundle/resources/cluster_policies/basic/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
envsubst < databricks.yml.tmpl > databricks.yml

trace $CLI bundle validate
trace $CLI bundle validate -o json | jq ".resources.cluster_policies"

trace $CLI bundle summary

cleanup() {
trace $CLI bundle destroy --auto-approve
rm -f out.requests.txt
}
trap cleanup EXIT
trace $CLI bundle deploy

# Mask the server-assigned policy id: the real backend returns a hex id that the
# built-in UUID replacement misses, so register it explicitly for cloud parity.
read_id.py test_cluster_policy > /dev/null

title "Verify the create request"
trace print_requests.py //policies/clusters/create

trace $CLI bundle summary

title "Update the cluster policy name"
Comment thread
Sankalp-Mittal marked this conversation as resolved.
trace update_file.py databricks.yml my_cluster_policy my_cluster_policy_2
trace $CLI bundle deploy

title "Verify the update request"
trace print_requests.py //policies/clusters/edit

trace $CLI bundle summary

title "Destroy the cluster policy"
trace $CLI bundle destroy --auto-approve

title "Verify the destroy request"
trace print_requests.py //policies/clusters/delete

trace $CLI bundle summary
Loading
Loading