Skip to content

Commit 095fcd5

Browse files
authored
[Fix] Fix filling of missing attributes in databricks_quality_monitor (#4519)
## Changes <!-- Summary of your changes that are easy to understand --> The quality monitor Get API doesn't return attributes `warehouse_id` and `skip_builtin_dashboard` set by the Create API, leading to configuration drift and errors. We can backfill them from the existing state. Resolves #4518 ## Tests <!-- How is this tested? Please see the checklist below and also describe any other relevant tests --> - [x] `make test` run locally - [ ] relevant change in `docs/` folder - [ ] covered with integration tests in `internal/acceptance` - [ ] using Go SDK - [ ] using TF Plugin Framework
1 parent 0f28b2a commit 095fcd5

File tree

7 files changed

+64
-9
lines changed

7 files changed

+64
-9
lines changed

NEXT_CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* Only allow `authorized_paths` to be updated in the `options` field of `databricks_catalog` ([#4517](https://github.com/databricks/terraform-provider-databricks/pull/4517)).
1414
* Mark `default_catalog_name` attribute in `databricks_metastore_assignment` as deprecated ([#4522](https://github.com/databricks/terraform-provider-databricks/pull/4522))
1515
* Delete `databricks_sql_endpoint` that failed to start ([#4520](https://github.com/databricks/terraform-provider-databricks/pull/4520))
16+
* Fix filling of missing attributes in `databricks_quality_monitor` ([#4519](https://github.com/databricks/terraform-provider-databricks/pull/4519)).
1617

1718
### Documentation
1819

@@ -25,4 +26,4 @@
2526

2627
### Internal Changes
2728

28-
* Bump golang version to 1.24.0 ([#4508](https://github.com/databricks/terraform-provider-databricks/pull/4508)).
29+
* Bump golang version to 1.24.0 ([#4508](https://github.com/databricks/terraform-provider-databricks/pull/4508)).

catalog/quality_monitor_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ resource "databricks_sql_table" "myInferenceTable" {
3232
name = "bar{var.STICKY_RANDOM}_inference"
3333
table_type = "MANAGED"
3434
data_source_format = "DELTA"
35+
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
3536
3637
column {
3738
name = "model_id"
@@ -79,6 +80,7 @@ func TestUcAccQualityMonitor(t *testing.T) {
7980
name = "bar{var.STICKY_RANDOM}_timeseries"
8081
table_type = "MANAGED"
8182
data_source_format = "DELTA"
83+
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
8284
8385
column {
8486
name = "timestamp"
@@ -106,6 +108,7 @@ func TestUcAccQualityMonitor(t *testing.T) {
106108
name = "bar{var.STICKY_RANDOM}_snapshot"
107109
table_type = "MANAGED"
108110
data_source_format = "DELTA"
111+
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
109112
110113
column {
111114
name = "timestamp"

catalog/resource_quality_monitor.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,18 @@ func ResourceQualityMonitor() common.Resource {
9090
return err
9191

9292
}
93-
return common.StructToData(endpoint, monitorSchema, d)
93+
oldWarehouseId := d.Get("warehouse_id").(string)
94+
oldSkipBuiltinDashboard := d.Get("skip_builtin_dashboard").(bool)
95+
96+
err = common.StructToData(endpoint, monitorSchema, d)
97+
if err != nil {
98+
return err
99+
}
100+
// we need this because Get API doesn't return that information
101+
d.Set("warehouse_id", oldWarehouseId)
102+
d.Set("skip_builtin_dashboard", oldSkipBuiltinDashboard)
103+
104+
return nil
94105
},
95106
Update: func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error {
96107
w, err := c.WorkspaceClient()

catalog/resource_quality_monitor_test.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ func TestQualityMonitorCreateTimeseries(t *testing.T) {
1818
MockWorkspaceClientFunc: func(w *mocks.MockWorkspaceClient) {
1919
e := w.GetMockQualityMonitorsAPI().EXPECT()
2020
e.Create(mock.Anything, catalog.CreateMonitor{
21-
TableName: "test_table",
22-
OutputSchemaName: "output.schema",
23-
AssetsDir: "sample.dir",
21+
TableName: "test_table",
22+
OutputSchemaName: "output.schema",
23+
AssetsDir: "sample.dir",
24+
WarehouseId: "1234",
25+
SkipBuiltinDashboard: true,
2426
TimeSeries: &catalog.MonitorTimeSeries{
2527
Granularities: []string{"1 day"},
2628
TimestampCol: "timestamp",
@@ -45,13 +47,18 @@ func TestQualityMonitorCreateTimeseries(t *testing.T) {
4547
table_name = "test_table",
4648
assets_dir = "sample.dir",
4749
output_schema_name = "output.schema",
50+
warehouse_id = "1234",
51+
skip_builtin_dashboard = true,
4852
time_series = {
4953
granularities = ["1 day"],
5054
timestamp_col = "timestamp"
5155
}
5256
`,
5357
Create: true,
54-
}.ApplyNoError(t)
58+
}.ApplyAndExpectData(t, map[string]any{
59+
"warehouse_id": "1234",
60+
"skip_builtin_dashboard": true,
61+
})
5562
}
5663

5764
func TestQualityMonitorCreateInference(t *testing.T) {

docs/resources/quality_monitor.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ subcategory: "Unity Catalog"
55

66
This resource allows you to manage [Lakehouse Monitors](https://docs.databricks.com/en/lakehouse-monitoring/index.html) in Databricks.
77

8-
A `databricks_quality_monitor` is attached to a [databricks_sql_table](sql_table.md) and can be of type timeseries, snapshot or inference.
8+
A `databricks_quality_monitor` is attached to a [databricks_sql_table](sql_table.md) and can be of type timeseries, snapshot or inference.
99

1010
## Plugin Framework Migration
11+
1112
The quality monitor resource has been migrated from sdkv2 to plugin framework。 If you encounter any problem with this resource and suspect it is due to the migration, you can fallback to sdkv2 by setting the environment variable in the following way `export USE_SDK_V2_RESOURCES="databricks_quality_monitor"`.
1213

1314
## Example Usage
@@ -114,9 +115,9 @@ table.
114115
* `schedule` - The schedule for automatically updating and refreshing metric tables. This block consists of following fields:
115116
* `quartz_cron_expression` - string expression that determines when to run the monitor. See [Quartz documentation](https://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html) for examples.
116117
* `timezone_id` - string with timezone id (e.g., `PST`) in which to evaluate the Quartz expression.
117-
* `skip_builtin_dashboard` - Whether to skip creating a default dashboard summarizing data quality metrics.
118+
* `skip_builtin_dashboard` - Whether to skip creating a default dashboard summarizing data quality metrics. (Can't be updated after creation).
118119
* `slicing_exprs` - List of column expressions to slice data with for targeted analysis. The data is grouped by each expression independently, resulting in a separate slice for each predicate and its complements. For high-cardinality columns, only the top 100 unique values by frequency will generate slices.
119-
* `warehouse_id` - Optional argument to specify the warehouse for dashboard creation. If not specified, the first running warehouse will be used.
120+
* `warehouse_id` - Optional argument to specify the warehouse for dashboard creation. If not specified, the first running warehouse will be used. (Can't be updated after creation)
120121

121122
## Attribute Reference
122123

internal/providers/pluginfw/products/qualitymonitor/resource_quality_monitor.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ func (r *QualityMonitorResource) Create(ctx context.Context, req resource.Create
146146

147147
// Set the ID to the table name
148148
newMonitorInfoTfSDK.ID = newMonitorInfoTfSDK.TableName
149+
// We need it to fill additional fields as they are not returned by the API
150+
newMonitorInfoTfSDK.WarehouseId = monitorInfoTfSDK.WarehouseId
151+
newMonitorInfoTfSDK.SkipBuiltinDashboard = monitorInfoTfSDK.SkipBuiltinDashboard
149152

150153
resp.Diagnostics.Append(resp.State.Set(ctx, newMonitorInfoTfSDK)...)
151154
}
@@ -179,6 +182,20 @@ func (r *QualityMonitorResource) Read(ctx context.Context, req resource.ReadRequ
179182
}
180183

181184
monitorInfoTfSDK.ID = monitorInfoTfSDK.TableName
185+
// We need it to fill additional fields as they are not returned by the API
186+
var origWarehouseId types.String
187+
var origSkipBuiltinDashboard types.Bool
188+
resp.Diagnostics.Append(req.State.GetAttribute(ctx, path.Root("warehouse_id"), &origWarehouseId)...)
189+
resp.Diagnostics.Append(req.State.GetAttribute(ctx, path.Root("skip_builtin_dashboard"), &origSkipBuiltinDashboard)...)
190+
if resp.Diagnostics.HasError() {
191+
return
192+
}
193+
if origWarehouseId.ValueString() != "" {
194+
monitorInfoTfSDK.WarehouseId = origWarehouseId
195+
}
196+
if origSkipBuiltinDashboard.ValueBool() {
197+
monitorInfoTfSDK.SkipBuiltinDashboard = origSkipBuiltinDashboard
198+
}
182199

183200
resp.Diagnostics.Append(resp.State.Set(ctx, monitorInfoTfSDK)...)
184201
}
@@ -225,6 +242,12 @@ func (r *QualityMonitorResource) Update(ctx context.Context, req resource.Update
225242
if resp.Diagnostics.HasError() {
226243
return
227244
}
245+
// We need it to fill additional fields as they are not returned by the API
246+
resp.Diagnostics.Append(req.State.GetAttribute(ctx, path.Root("warehouse_id"), &newMonitorInfoTfSDK.WarehouseId)...)
247+
resp.Diagnostics.Append(req.State.GetAttribute(ctx, path.Root("skip_builtin_dashboard"), &newMonitorInfoTfSDK.SkipBuiltinDashboard)...)
248+
if resp.Diagnostics.HasError() {
249+
return
250+
}
228251

229252
resp.Diagnostics.Append(resp.State.Set(ctx, newMonitorInfoTfSDK)...)
230253
}

internal/providers/pluginfw/products/qualitymonitor/resource_quality_monitor_acc_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ resource "databricks_sql_table" "myInferenceTable" {
3535
name = "bar{var.STICKY_RANDOM}_inference"
3636
table_type = "MANAGED"
3737
data_source_format = "DELTA"
38+
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
3839
3940
column {
4041
name = "model_id"
@@ -63,6 +64,7 @@ func TestUcAccQualityMonitor(t *testing.T) {
6364
table_name = databricks_sql_table.myInferenceTable.id
6465
assets_dir = "/Shared/provider-test/databricks_quality_monitoring/${databricks_sql_table.myInferenceTable.name}"
6566
output_schema_name = databricks_schema.things.id
67+
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
6668
inference_log {
6769
granularities = ["1 day"]
6870
timestamp_col = "timestamp"
@@ -78,6 +80,7 @@ func TestUcAccQualityMonitor(t *testing.T) {
7880
name = "bar{var.STICKY_RANDOM}_timeseries"
7981
table_type = "MANAGED"
8082
data_source_format = "DELTA"
83+
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
8184
8285
column {
8386
name = "timestamp"
@@ -89,6 +92,7 @@ func TestUcAccQualityMonitor(t *testing.T) {
8992
table_name = databricks_sql_table.myTimeseries.id
9093
assets_dir = "/Shared/provider-test/databricks_quality_monitoring/${databricks_sql_table.myTimeseries.name}"
9194
output_schema_name = databricks_schema.things.id
95+
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
9296
time_series {
9397
granularities = ["1 day"]
9498
timestamp_col = "timestamp"
@@ -101,6 +105,7 @@ func TestUcAccQualityMonitor(t *testing.T) {
101105
name = "bar{var.STICKY_RANDOM}_snapshot"
102106
table_type = "MANAGED"
103107
data_source_format = "DELTA"
108+
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
104109
105110
column {
106111
name = "timestamp"
@@ -112,6 +117,7 @@ func TestUcAccQualityMonitor(t *testing.T) {
112117
table_name = databricks_sql_table.mySnapshot.id
113118
assets_dir = "/Shared/provider-test/databricks_quality_monitoring/${databricks_sql_table.myTimeseries.name}"
114119
output_schema_name = databricks_schema.things.id
120+
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
115121
snapshot {
116122
}
117123
}
@@ -129,6 +135,7 @@ func TestUcAccUpdateQualityMonitor(t *testing.T) {
129135
table_name = databricks_sql_table.myInferenceTable.id
130136
assets_dir = "/Shared/provider-test/databricks_quality_monitoring/${databricks_sql_table.myInferenceTable.name}"
131137
output_schema_name = databricks_schema.things.id
138+
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
132139
inference_log {
133140
granularities = ["1 day"]
134141
timestamp_col = "timestamp"
@@ -144,6 +151,7 @@ func TestUcAccUpdateQualityMonitor(t *testing.T) {
144151
table_name = databricks_sql_table.myInferenceTable.id
145152
assets_dir = "/Shared/provider-test/databricks_quality_monitoring/${databricks_sql_table.myInferenceTable.name}"
146153
output_schema_name = databricks_schema.things.id
154+
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
147155
inference_log {
148156
granularities = ["1 hour"]
149157
timestamp_col = "timestamp"
@@ -228,6 +236,7 @@ func TestUcAccUpdateQualityMonitorTransitionFromPluginFw(t *testing.T) {
228236
table_name = databricks_sql_table.myInferenceTable.id
229237
assets_dir = "/Shared/provider-test/databricks_quality_monitoring/${databricks_sql_table.myInferenceTable.name}"
230238
output_schema_name = databricks_schema.things.id
239+
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
231240
inference_log {
232241
granularities = ["1 hour"]
233242
timestamp_col = "timestamp"

0 commit comments

Comments
 (0)