Skip to content

Commit 2534bb0

Browse files
authored
Fix app resource drift on config field (#7326)
## Changes Fix `bundle plan` reporting an update to an app's `config.env` values on every run, which also redeployed the app on every `bundle deploy`. The Apps API returns environment variable names only, so `value` and `value_from` are no longer compared against the remote deployment ## Why Fixes #7301 ## Tests Added acceptance test <!-- If your PR needs to be included in the release notes for next release, add a changelog fragment: create .nextchanges/<section>/<name>.md with a one-line description (e.g. .nextchanges/cli/quickstart.md). See .nextchanges/README.md. -->
1 parent 8feaaa9 commit 2534bb0

11 files changed

Lines changed: 160 additions & 19 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* Fix `bundle plan` reporting an update to an app's `config.env` values on every run, which also redeployed the app on every `bundle deploy`. The Apps API returns environment variable names only, so `value` and `value_from` are no longer compared against the remote deployment. ([#7326](https://github.com/databricks/cli/pull/7326))

‎acceptance/bundle/resources/apps/config-drift-stopped/output.txt‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ Resources: 1 created, 0 changed, 0 deleted, 0 unchanged
1515
"config.env[0].value": {
1616
"action": "update",
1717
"old": "original_value",
18-
"new": "changed_value",
19-
"remote": "original_value"
18+
"new": "changed_value"
2019
}
2120
}
2221

‎acceptance/bundle/resources/apps/config-drift/out.plan.direct.json‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,10 @@
3232
],
3333
"remote": [
3434
{
35-
"name": "MY_VAR",
36-
"value": "changed_value"
35+
"name": "MY_VAR"
3736
},
3837
{
39-
"name": "NEW_VAR",
40-
"value": "new_value"
38+
"name": "NEW_VAR"
4139
}
4240
]
4341
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import http.server, os
2+
3+
http.server.HTTPServer(
4+
("", int(os.environ["DATABRICKS_APP_PORT"])), http.server.SimpleHTTPRequestHandler
5+
).serve_forever()
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
bundle:
2+
name: apps-config-env-no-drift
3+
4+
resources:
5+
apps:
6+
myapp:
7+
name: myapp
8+
source_code_path: ./app
9+
resources:
10+
- name: my-secret
11+
secret:
12+
scope: my-scope
13+
key: my-key
14+
permission: READ
15+
config:
16+
command:
17+
- python
18+
- app.py
19+
env:
20+
- name: GREETING
21+
value: hello
22+
- name: API_TOKEN
23+
value_from: my-secret
24+
lifecycle:
25+
started: true
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Cloud = false
2+
EnvMatrix.DMS = ["", "true"]
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
2+
=== Deploy a started app with config.env entries set via value and value_from
3+
>>> [CLI] bundle deploy
4+
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/apps-config-env-no-drift/default/files...
5+
✓ Deployment succeeded
6+
Created apps.myapp
7+
Files: 2 uploaded, 0 deleted
8+
Resources: 1 created, 0 changed, 0 deleted, 0 unchanged
9+
10+
=== The Apps API returns deployment env vars with their name only
11+
>>> [CLI] bundle plan -o json
12+
[
13+
{
14+
"name": "GREETING"
15+
},
16+
{
17+
"name": "API_TOKEN"
18+
}
19+
]
20+
21+
=== Re-plan is clean: value and value_from are input-only and must not drift
22+
>>> [CLI] bundle plan
23+
Plan: 0 to add, 0 to change, 0 to delete, 1 unchanged
24+
25+
>>> [CLI] bundle plan -o json
26+
{
27+
"config.env[0].value": {
28+
"action": "skip",
29+
"reason": "input_only",
30+
"old": "hello",
31+
"new": "hello"
32+
},
33+
"config.env[1].value_from": {
34+
"action": "skip",
35+
"reason": "input_only",
36+
"old": "my-secret",
37+
"new": "my-secret"
38+
}
39+
}
40+
41+
=== A local change to an env value still plans an update
42+
>>> update_file.py databricks.yml value: hello value: goodbye
43+
44+
>>> [CLI] bundle plan
45+
update apps.myapp
46+
47+
Plan: 0 to add, 1 to change, 0 to delete, 0 unchanged
48+
49+
>>> [CLI] bundle plan -o json
50+
{
51+
"config.env[0].value": {
52+
"action": "update",
53+
"old": "hello",
54+
"new": "goodbye"
55+
},
56+
"config.env[1].value_from": {
57+
"action": "skip",
58+
"reason": "input_only",
59+
"old": "my-secret",
60+
"new": "my-secret"
61+
}
62+
}
63+
64+
=== Deploy applies the change and the plan is clean again
65+
>>> [CLI] bundle deploy
66+
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/apps-config-env-no-drift/default/files...
67+
✓ Deployment succeeded
68+
Updated apps.myapp
69+
Files: 1 uploaded, 0 deleted
70+
Resources: 0 created, 1 changed, 0 deleted, 0 unchanged
71+
72+
>>> [CLI] bundle plan
73+
Plan: 0 to add, 0 to change, 0 to delete, 1 unchanged
74+
75+
>>> [CLI] bundle destroy --auto-approve
76+
The following resources will be deleted:
77+
delete resources.apps.myapp
78+
79+
All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/apps-config-env-no-drift/default
80+
81+
Destroy: 1 deleted
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
cleanup() {
2+
trace $CLI bundle destroy --auto-approve
3+
}
4+
trap cleanup EXIT
5+
6+
title "Deploy a started app with config.env entries set via value and value_from"
7+
trace $CLI bundle deploy
8+
9+
title "The Apps API returns deployment env vars with their name only"
10+
trace $CLI bundle plan -o json | nostamp | jq '.plan."resources.apps.myapp".remote_state.config.env'
11+
12+
title "Re-plan is clean: value and value_from are input-only and must not drift"
13+
trace $CLI bundle plan | contains.py "Plan: 0 to add, 0 to change, 0 to delete, 1 unchanged"
14+
trace $CLI bundle plan -o json | nostamp | jq '.plan."resources.apps.myapp".changes // {} | with_entries(select(.key | startswith("config.env")))'
15+
16+
title "A local change to an env value still plans an update"
17+
trace update_file.py databricks.yml "value: hello" "value: goodbye"
18+
trace $CLI bundle plan | contains.py "Plan: 0 to add, 1 to change, 0 to delete, 0 unchanged"
19+
trace $CLI bundle plan -o json | nostamp | jq '.plan."resources.apps.myapp".changes // {} | with_entries(select(.key | startswith("config.env")))'
20+
21+
title "Deploy applies the change and the plan is clean again"
22+
trace $CLI bundle deploy
23+
trace $CLI bundle plan | contains.py "Plan: 0 to add, 0 to change, 0 to delete, 1 unchanged"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# The Apps API returns deployment env vars with their name only, so config.env value and
2+
# value_from are classified input-only (ignore_remote_changes) and the fake server models
3+
# that masking. A real workspace would need the referenced secret to exist, so this runs
4+
# locally only. See https://github.com/databricks/cli/issues/7301
5+
RecordRequests = false

‎bundle/direct/dresources/configs/apps.yml‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,10 @@ backend_defaults:
1818
ignore_remote_changes:
1919
- field: space # This field is not yet supported by Update APIs but exposed in the API spec. TODO: fix when update APIs supports it.
2020
reason: managed
21+
# The Apps API returns deployment env vars with their name only: value and value_from are
22+
# never read back, so the remote side is always empty and would otherwise plan an update
23+
# on every run. See https://github.com/databricks/cli/issues/7301
24+
- field: config.env[*].value
25+
reason: input_only
26+
- field: config.env[*].value_from
27+
reason: input_only

0 commit comments

Comments
 (0)