[Fix] Preserve externally set spark_env_vars during databricks_cluster updates when ignore_changes is used#5438
Conversation
When spark_env_vars are set externally (e.g. by cluster policies) but not in the user's Terraform config, the Edit API would clear them because the full replacement semantics treat omission as deletion. This carries over existing spark_env_vars from the current cluster state when the user config has none.
Add truth table documenting all four scenarios for spark_env_vars preservation logic. Update changelog to mention lifecycle ignore_changes fix.
When spark_env_vars are set externally (e.g. by cluster policies) but not in the user's Terraform config, the Edit API would clear them because the full replacement semantics treat omission as deletion. This carries over existing spark_env_vars from the current cluster state when the user config has none.
Add truth table documenting all four scenarios for spark_env_vars preservation logic. Update changelog to mention lifecycle ignore_changes fix.
spark_env_vars during databricks_cluster updatesspark_env_vars during databricks_cluster updates when ignore_changes is used
| if len(cluster.SparkEnvVars) == 0 && len(clusterInfo.SparkEnvVars) > 0 { | ||
| cluster.SparkEnvVars = clusterInfo.SparkEnvVars | ||
| } |
There was a problem hiding this comment.
@jlieow if Edit does full replacement, isn't the expected behaviour for terraform apply that whatever is in the config is applied? Should these variables be part of config then?
There was a problem hiding this comment.
This is related to #1238. In that issue, we can see that users are trying to manage parts of the resource in Terraform and others in the UI.
The user is attempting to use ignore_changes to let Terraform and an external process manage different parts of the same object, which is what ignore_changes is supposed to do as per the lifecycle reference doc.
However, due to the full replacement behaviour of the Edit API, this breaks the Terraform lifecycle behaviour. ignore_changes only suppresses drift detection in the plan, but the provider still sends an empty map to the API, which clears the externally-set values. This impacts users who manage this resource via multiple processes.
This fix assumes that native Terraform features like ignore_changes should take precedence since these are core features that users expect to work across all resources and not be tied to API limitations.
| ### Documentation | ||
| * Fixed `databricks_cluster` to preserve externally-set `spark_env_vars` (e.g. from cluster policies) during updates when not configured in Terraform. This also fixes `lifecycle { ignore_changes = [spark_env_vars] }` which previously failed to prevent deletion of externally-set values ([#1238](https://github.com/databricks/terraform-provider-databricks/issues/1238)). | ||
|
|
||
| * Added documentation note about whitespace handling in `MAP` column types for `databricks_sql_table`. |
There was a problem hiding this comment.
This shouldn't be removed
There was a problem hiding this comment.
I have amended the commit and restored the note.
51868da to
ec304d7
Compare
|
If integration tests don't run automatically, an authorized user can run them manually by following the instructions below: Trigger: Inputs:
Checks will be approved automatically on success. |
Related to #1238
Changes
When
spark_env_varsare set externally (e.g. by cluster policies or manual edits) but not declared in the Terraform config, updating any other cluster field (likecluster_name) causes the Edit API to wipe those env vars. This happens because the Clusters Edit API (POST /api/2.1/clusters/edit) does a full replacement — omitted fields are cleared. The provider was sending nil forspark_env_varssinceStructToDataskips writing API-returned values to state when the field is not in the user's config.This fix carries over existing
spark_env_varsfrom the current cluster state into the Edit request when the user has not configured any. This also fixeslifecycle { ignore_changes = [spark_env_vars] }which previously had nothing to preserve.No schema changes. No changes to Read behavior.
Detailed Changes
Preserve spark_env_vars in update path (
clusters/resource_cluster.go, lines 622-636)Before:
After:
Why: The
EditClusterstruct is built from Terraform state viaDataToStructPointer(line 546). Whenspark_env_varsis not in the user's config, state has no value for it, socluster.SparkEnvVarsis nil. The Edit API interprets this as "clear spark_env_vars". The current cluster details are already fetched at line 578 (clusterInfo), so we carry over the existing env vars when the user hasn't configured any.Tests
TestResourceClusterUpdate_PreservesExternalSparkEnvVars: Simulates an update where the cluster GET returns
spark_env_varsset externally (PYSPARK_PYTHON,ENV_FROM_POLICY) but the user's Terraform state has nospark_env_vars. Asserts viaExpectedRequestthat the Edit API call includes the externally-set env vars rather than omitting them.make testrun locallyrelevant change in
docs/foldercovered with integration tests in
internal/acceptanceusing Go SDK
using TF Plugin Framework
has entry in
NEXT_CHANGELOG.mdfile