Skip to content

Commit c84430d

Browse files
authored
Update Customer Managed Keys & MWS workspace to match new API (#642)
Due the changes in the Accounts API we need to do following changes: * Add required attribute `use_cases` to `databricks_mws_customer_managed_keys` resource * The `customer_managed_key_id` field in `databricks_mws_workspaces` resource is deprecated and should be replaced with `managed_services_customer_managed_key_id` (and optionally `storage_customer_managed_key_id`). The `customer_managed_key_id` field is left for compatibility, and automatically converted into `managed_services_customer_managed_key_id`. It will be completely removed in the next versions This fixes #641
1 parent 16a23d4 commit c84430d

File tree

10 files changed

+351
-177
lines changed

10 files changed

+351
-177
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
* Fixed state refresh bugs in `databricks_sql_permissions` ([#620](https://github.com/databrickslabs/terraform-provider-databricks/issues/620), [#619](https://github.com/databrickslabs/terraform-provider-databricks/issues/620))
66
* Fixed `workspace_ids_filter` mapping for `databricks_mws_log_delivery` ([#635](https://github.com/databrickslabs/terraform-provider-databricks/issues/635))
77

8+
**Behavior changes**
9+
10+
* The `customer_managed_key_id` field in `databricks_mws_workspaces` resource is deprecated and should be replaced with `managed_services_customer_managed_key_id` (and optionally `storage_customer_managed_key_id`). `databricks_mws_customer_managed_keys` now requires the parameter `use_cases` ([#642](https://github.com/databrickslabs/terraform-provider-databricks/pull/642))
11+
812
## 0.3.3
913

1014
* Added resources for SQL Analytics queries and dashboards: `databricks_sql_query`, `databricks_sql_visualization`, `databricks_sql_dashboard`, `databricks_sql_widget` ([#553](https://github.com/databrickslabs/terraform-provider-databricks/pull/553))

docs/resources/mws_customer_managed_keys.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ resource "databricks_mws_customer_managed_keys" "my_cmk" {
4040
key_arn = aws_kms_key.customer_managed_key.arn
4141
key_alias = aws_kms_alias.customer_managed_key_alias.name
4242
}
43+
use_cases = ["MANAGED_SERVICES", "STORAGE"]
4344
}
4445
```
4546

@@ -50,6 +51,9 @@ The following arguments are required:
5051

5152
* `aws_key_info` - This field is a block and is documented below.
5253
* `account_id` - Account Id that could be found in the bottom left corner of [Accounts Console](https://accounts.cloud.databricks.com/)
54+
* `use_cases` - list of use cases for which this key will be used. Possible values are:
55+
* `MANAGED_SERVICES` - for encryption of the workspace objects (notebooks, secrets) that are stored in the control plane
56+
* `STORAGE` - for encryption of the DBFS Storage & Cluster EBS Volumes
5357

5458

5559
### aws_key_info Configuration Block

docs/resources/mws_workspaces.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,9 @@ The following arguments are available:
179179
* `network_id` - (Optional) `network_id` from [networks](mws_networks.md)
180180
* `account_id` - Account Id that could be found in the bottom left corner of [Accounts Console](https://accounts.cloud.databricks.com/).
181181
* `credentials_id` - `credentials_id` from [credentials](mws_credentials.md)
182-
* `customer_managed_key_id` - (Optional) `customer_managed_key_id` from [customer managed keys](mws_customer_managed_keys.md)
182+
* `customer_managed_key_id` - (Optional, **Deprecated**, see `managed_services_customer_managed_key_id` and `storage_customer_managed_key_id`) `customer_managed_key_id` from [customer managed keys](mws_customer_managed_keys.md)
183+
* `managed_services_customer_managed_key_id` - (Optional) `customer_managed_key_id` from [customer managed keys](mws_customer_managed_keys.md) with `use_cases` set to `MANAGED_SERVICES`. This is used to encrypt the workspace's notebook and secret data in the control plane.
184+
* `storage_customer_managed_key_id` - (Optional, **Deprecated**) `customer_managed_key_id` from [customer managed keys](mws_customer_managed_keys.md) with `use_cases` set to `STORAGE`. This is used to encrypt the DBFS Storage & Cluster EBS Volumes.
183185
* `deployment_name` - part of URL: `https://<deployment-name>.cloud.databricks.com`
184186
* `workspace_name` - name of the workspace, will appear on UI
185187
* `aws_region` - AWS region of VPC
@@ -214,4 +216,4 @@ You can reset local DNS caches before provisioning new workspaces with one of th
214216
* Mac OS Sierra, X El Capitan, X Mavericks, X Mountain Lion, or X Lion - `sudo killall -HUP mDNSResponder`
215217
* Mac OS X Yosemite - `sudo discoveryutil udnsflushcaches`
216218
* Mac OS X Snow Leopard - `sudo dscacheutil -flushcache`
217-
* Mac OS X Leopard and below - `sudo lookupd -flushcache`
219+
* Mac OS X Leopard and below - `sudo lookupd -flushcache`

mws/acceptance/cmk_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ func TestMwsAccCustomerManagedKeys(t *testing.T) {
2525
key_arn = "{env.TEST_KMS_KEY_ARN}"
2626
key_alias = "{env.TEST_KMS_KEY_ALIAS}"
2727
}
28+
use_cases = ["MANAGED_SERVICES"]
2829
}`,
2930
},
3031
})

mws/acceptance/workspace_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ func TestMwsAccWorkspaces(t *testing.T) {
2626
key_arn = "{env.TEST_KMS_KEY_ARN}"
2727
key_alias = "{env.TEST_KMS_KEY_ALIAS}"
2828
}
29+
use_cases = ["STORAGE", "MANAGED_SERVICES"]
2930
}
3031
resource "databricks_mws_storage_configurations" "this" {
3132
account_id = "{env.DATABRICKS_ACCOUNT_ID}"
@@ -52,7 +53,7 @@ func TestMwsAccWorkspaces(t *testing.T) {
5253
5354
credentials_id = databricks_mws_credentials.this.credentials_id
5455
storage_configuration_id = databricks_mws_storage_configurations.this.storage_configuration_id
55-
customer_managed_key_id = databricks_mws_customer_managed_keys.this.customer_managed_key_id
56+
managed_services_customer_managed_key_id = databricks_mws_customer_managed_keys.this.customer_managed_key_id
5657
network_id = databricks_mws_networks.this.network_id
5758
}`,
5859
},

mws/mws.go

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -75,22 +75,24 @@ var WorkspaceStatusesNonRunnable = []string{WorkspaceStatusCanceled, WorkspaceSt
7575

7676
// Workspace is the object that contains all the information for deploying a workspace
7777
type Workspace struct {
78-
AccountID string `json:"account_id"`
79-
WorkspaceName string `json:"workspace_name"`
80-
DeploymentName string `json:"deployment_name"`
81-
AwsRegion string `json:"aws_region"`
82-
CredentialsID string `json:"credentials_id"`
83-
StorageConfigurationID string `json:"storage_configuration_id"`
84-
CustomerManagedKeyID string `json:"customer_managed_key_id,omitempty"`
85-
PricingTier string `json:"pricing_tier,omitempty" tf:"computed"`
86-
PrivateAccessSettingsID string `json:"private_access_settings_id,omitempty"`
87-
NetworkID string `json:"network_id,omitempty"`
88-
IsNoPublicIPEnabled bool `json:"is_no_public_ip_enabled,omitempty"`
89-
WorkspaceID int64 `json:"workspace_id,omitempty" tf:"computed"`
90-
WorkspaceURL string `json:"workspace_url,omitempty" tf:"computed"`
91-
WorkspaceStatus string `json:"workspace_status,omitempty" tf:"computed"`
92-
WorkspaceStatusMessage string `json:"workspace_status_message,omitempty" tf:"computed"`
93-
CreationTime int64 `json:"creation_time,omitempty" tf:"computed"`
78+
AccountID string `json:"account_id"`
79+
WorkspaceName string `json:"workspace_name"`
80+
DeploymentName string `json:"deployment_name"`
81+
AwsRegion string `json:"aws_region"`
82+
CredentialsID string `json:"credentials_id"`
83+
CustomerManagedKeyID string `json:"customer_managed_key_id,omitempty"` // just for compatibility, will be removed
84+
StorageConfigurationID string `json:"storage_configuration_id"`
85+
ManagedServicesCustomerManagedKeyID string `json:"managed_services_customer_managed_key_id,omitempty"`
86+
StoragexCustomerManagedKeyID string `json:"storage_customer_managed_key_id,omitempty"`
87+
PricingTier string `json:"pricing_tier,omitempty" tf:"computed"`
88+
PrivateAccessSettingsID string `json:"private_access_settings_id,omitempty"`
89+
NetworkID string `json:"network_id,omitempty"`
90+
IsNoPublicIPEnabled bool `json:"is_no_public_ip_enabled,omitempty"`
91+
WorkspaceID int64 `json:"workspace_id,omitempty" tf:"computed"`
92+
WorkspaceURL string `json:"workspace_url,omitempty" tf:"computed"`
93+
WorkspaceStatus string `json:"workspace_status,omitempty" tf:"computed"`
94+
WorkspaceStatusMessage string `json:"workspace_status_message,omitempty" tf:"computed"`
95+
CreationTime int64 `json:"creation_time,omitempty" tf:"computed"`
9496
}
9597

9698
// VPCEndpoint is the object that contains all the information for registering an VPC endpoint

mws/resource_customer_managed_key.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type CustomerManagedKey struct {
2222
AwsKeyInfo *AwsKeyInfo `json:"aws_key_info"`
2323
AccountID string `json:"account_id"`
2424
CreationTime int64 `json:"creation_time,omitempty" tf:"computed"`
25+
UseCases []string `json:"use_cases"`
2526
}
2627

2728
// NewCustomerManagedKeysAPI creates CustomerManagedKeysAPI instance from provider meta

mws/resource_customer_managed_key_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ func TestMwsAccCustomerManagedKeys(t *testing.T) {
2929
KeyAlias: kmsKeyAlias,
3030
},
3131
AccountID: acctID,
32+
UseCases: []string{"MANAGED_SERVICES"},
3233
})
3334
assert.NoError(t, err, err)
3435

@@ -56,6 +57,7 @@ func TestResourceCustomerManagedKeyCreate(t *testing.T) {
5657
KeyArn: "key-arn",
5758
KeyAlias: "key-alias",
5859
},
60+
UseCases: []string{"MANAGED_SERVICES"},
5961
},
6062
Response: CustomerManagedKey{
6163
CustomerManagedKeyID: "cmkid",
@@ -72,6 +74,7 @@ func TestResourceCustomerManagedKeyCreate(t *testing.T) {
7274
KeyRegion: "us-east-1",
7375
},
7476
AccountID: "abc",
77+
UseCases: []string{"MANAGED_SERVICES"},
7578
CreationTime: 123,
7679
},
7780
},
@@ -84,6 +87,7 @@ func TestResourceCustomerManagedKeyCreate(t *testing.T) {
8487
key_arn = "key-arn"
8588
key_alias = "key-alias"
8689
}
90+
use_cases = ["MANAGED_SERVICES"]
8791
`,
8892
Create: true,
8993
}.Apply(t)
@@ -105,6 +109,7 @@ func TestResourceCustomerManagedKeyCreate_Error(t *testing.T) {
105109
KeyArn: "key-arn",
106110
KeyAlias: "key-alias",
107111
},
112+
UseCases: []string{"MANAGED_SERVICE"},
108113
},
109114
Response: common.APIErrorBody{
110115
ErrorCode: "INVALID_REQUEST",
@@ -122,6 +127,7 @@ func TestResourceCustomerManagedKeyCreate_Error(t *testing.T) {
122127
KeyAlias: "key-alias",
123128
KeyRegion: "us-east-1",
124129
},
130+
UseCases: []string{"MANAGED_SERVICE"},
125131
AccountID: "abc",
126132
CreationTime: 123,
127133
},
@@ -135,6 +141,7 @@ func TestResourceCustomerManagedKeyCreate_Error(t *testing.T) {
135141
key_arn = "key-arn"
136142
key_alias = "key-alias"
137143
}
144+
use_cases = ["MANAGED_SERVICE"]
138145
`,
139146
Create: true,
140147
}.Apply(t)
@@ -154,6 +161,7 @@ func TestResourceCustomerManagedKeyRead(t *testing.T) {
154161
KeyAlias: "key-alias",
155162
KeyRegion: "us-east-1",
156163
},
164+
UseCases: []string{"MANAGED_SERVICES"},
157165
AccountID: "abc",
158166
CreationTime: 123,
159167
},
@@ -167,6 +175,7 @@ func TestResourceCustomerManagedKeyRead(t *testing.T) {
167175
key_arn = "key-arn"
168176
key_alias = "key-alias"
169177
}
178+
use_cases = ["MANAGED_SERVICES"]
170179
`,
171180
ID: "abc/cmkid",
172181
Read: true,
@@ -176,6 +185,7 @@ func TestResourceCustomerManagedKeyRead(t *testing.T) {
176185
assert.Equal(t, "key-arn", d.Get("aws_key_info.0.key_arn"))
177186
assert.Equal(t, "key-alias", d.Get("aws_key_info.0.key_alias"))
178187
assert.Equal(t, "us-east-1", d.Get("aws_key_info.0.key_region"))
188+
assert.Equal(t, []interface{}{"MANAGED_SERVICES"}, d.Get("use_cases"))
179189
assert.Equal(t, "abc", d.Get("account_id"))
180190
assert.Equal(t, 123, d.Get("creation_time"))
181191
assert.Equal(t, "cmkid", d.Get("customer_managed_key_id"))
@@ -201,6 +211,7 @@ func TestResourceCustomerManagedKeyRead_NotFound(t *testing.T) {
201211
key_arn = "key-arn"
202212
key_alias = "key-alias"
203213
}
214+
use_cases = ["MANAGED_SERVICES"]
204215
`,
205216
ID: "abc/cmkid",
206217
Read: true,
@@ -225,6 +236,7 @@ func TestResourceCustomerManagedKeyDelete(t *testing.T) {
225236
key_arn = "key-arn"
226237
key_alias = "key-alias"
227238
}
239+
use_cases = ["MANAGED_SERVICES"]
228240
`,
229241
ID: "abc/cmkid",
230242
Delete: true,

mws/resource_workspace.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,13 @@ func (a WorkspacesAPI) WaitForRunning(ws Workspace, timeout time.Duration) error
108108
func (a WorkspacesAPI) Patch(ws Workspace, timeout time.Duration) error {
109109
workspacesAPIPath := fmt.Sprintf("/accounts/%s/workspaces/%d", ws.AccountID, ws.WorkspaceID)
110110
err := a.client.Patch(a.context, workspacesAPIPath, Workspace{
111-
AwsRegion: ws.AwsRegion,
112-
CredentialsID: ws.CredentialsID,
113-
StorageConfigurationID: ws.StorageConfigurationID,
114-
IsNoPublicIPEnabled: ws.IsNoPublicIPEnabled,
115-
NetworkID: ws.NetworkID,
116-
CustomerManagedKeyID: ws.CustomerManagedKeyID,
111+
AwsRegion: ws.AwsRegion,
112+
CredentialsID: ws.CredentialsID,
113+
StorageConfigurationID: ws.StorageConfigurationID,
114+
IsNoPublicIPEnabled: ws.IsNoPublicIPEnabled,
115+
NetworkID: ws.NetworkID,
116+
ManagedServicesCustomerManagedKeyID: ws.ManagedServicesCustomerManagedKeyID,
117+
StoragexCustomerManagedKeyID: ws.StoragexCustomerManagedKeyID,
117118
})
118119
if err != nil {
119120
return err
@@ -178,6 +179,10 @@ func ResourceWorkspace() *schema.Resource {
178179
return !strings.HasSuffix(new, old)
179180
}
180181
s["is_no_public_ip_enabled"].Default = false
182+
s["customer_managed_key_id"].Deprecated = "Use managed_services_customer_managed_key_id instead"
183+
s["customer_managed_key_id"].ConflictsWith = []string{"managed_services_customer_managed_key_id", "storage_customer_managed_key_id"}
184+
s["managed_services_customer_managed_key_id"].ConflictsWith = []string{"customer_managed_key_id"}
185+
s["storage_customer_managed_key_id"].ConflictsWith = []string{"customer_managed_key_id"}
181186
return s
182187
})
183188
p := common.NewPairSeparatedID("account_id", "workspace_id", "/").Schema(
@@ -193,6 +198,11 @@ func ResourceWorkspace() *schema.Resource {
193198
if err := common.DataToStructPointer(d, s, &workspace); err != nil {
194199
return err
195200
}
201+
if len(workspace.CustomerManagedKeyID) > 0 && len(workspace.ManagedServicesCustomerManagedKeyID) == 0 {
202+
log.Print("[INFO] Using existing customer_managed_key_id as value for new managed_services_customer_managed_key_id")
203+
workspace.ManagedServicesCustomerManagedKeyID = workspace.CustomerManagedKeyID
204+
workspace.CustomerManagedKeyID = ""
205+
}
196206
if err := workspacesAPI.Create(&workspace, d.Timeout(schema.TimeoutCreate)); err != nil {
197207
return err
198208
}
@@ -222,6 +232,11 @@ func ResourceWorkspace() *schema.Resource {
222232
if err := common.DataToStructPointer(d, s, &workspace); err != nil {
223233
return err
224234
}
235+
if len(workspace.CustomerManagedKeyID) > 0 && len(workspace.ManagedServicesCustomerManagedKeyID) == 0 {
236+
log.Print("[INFO] Using existing customer_managed_key_id as value for new managed_services_customer_managed_key_id")
237+
workspace.ManagedServicesCustomerManagedKeyID = workspace.CustomerManagedKeyID
238+
workspace.CustomerManagedKeyID = ""
239+
}
225240
return workspacesAPI.Patch(workspace, d.Timeout(schema.TimeoutUpdate))
226241
},
227242
Delete: func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error {

0 commit comments

Comments
 (0)