Skip to content

Commit 42e8c2a

Browse files
authored
azurerm_machine_learning_workspace - encryption block (hashicorp#14120)
Support Customer-managed key data encryption
1 parent a1fa302 commit 42e8c2a

File tree

3 files changed

+223
-1
lines changed

3 files changed

+223
-1
lines changed

internal/services/machinelearning/machine_learning_workspace_resource.go

+57
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,27 @@ func resourceMachineLearningWorkspace() *pluginsdk.Resource {
141141
Optional: true,
142142
},
143143

144+
"encryption": {
145+
Type: pluginsdk.TypeList,
146+
Optional: true,
147+
ForceNew: true,
148+
MaxItems: 1,
149+
Elem: &pluginsdk.Resource{
150+
Schema: map[string]*pluginsdk.Schema{
151+
"key_vault_id": {
152+
Type: pluginsdk.TypeString,
153+
Required: true,
154+
ValidateFunc: keyVaultValidate.VaultID,
155+
},
156+
"key_id": {
157+
Type: pluginsdk.TypeString,
158+
Required: true,
159+
ValidateFunc: validation.IsURLWithHTTPorHTTPS,
160+
},
161+
},
162+
},
163+
},
164+
144165
"friendly_name": {
145166
Type: pluginsdk.TypeString,
146167
Optional: true,
@@ -204,6 +225,7 @@ func resourceMachineLearningWorkspaceCreate(d *pluginsdk.ResourceData, meta inte
204225
ApplicationInsights: utils.String(d.Get("application_insights_id").(string)),
205226
KeyVault: utils.String(d.Get("key_vault_id").(string)),
206227
AllowPublicAccessWhenBehindVnet: utils.Bool(d.Get("public_network_access_enabled").(bool)),
228+
Encryption: expandMachineLearningWorkspaceEncryption(d.Get("encryption").([]interface{})),
207229
},
208230
}
209231

@@ -290,6 +312,10 @@ func resourceMachineLearningWorkspaceRead(d *pluginsdk.ResourceData, meta interf
290312
return fmt.Errorf("flattening identity on Workspace %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err)
291313
}
292314

315+
if err := d.Set("encryption", flattenMachineLearningWorkspaceEncryption(resp.Encryption)); err != nil {
316+
return fmt.Errorf("flattening encryption on Workspace %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err)
317+
}
318+
293319
return tags.FlattenAndSet(d, resp.Tags)
294320
}
295321

@@ -391,3 +417,34 @@ func flattenMachineLearningWorkspaceIdentity(identity *machinelearningservices.I
391417
},
392418
}
393419
}
420+
421+
func expandMachineLearningWorkspaceEncryption(input []interface{}) *machinelearningservices.EncryptionProperty {
422+
if len(input) == 0 || input[0] == nil {
423+
return nil
424+
}
425+
426+
raw := input[0].(map[string]interface{})
427+
encryption := &machinelearningservices.EncryptionProperty{
428+
Status: machinelearningservices.EncryptionStatusEnabled,
429+
}
430+
431+
encryption.KeyVaultProperties = &machinelearningservices.KeyVaultProperties{
432+
KeyVaultArmID: utils.String(raw["key_vault_id"].(string)),
433+
KeyIdentifier: utils.String(raw["key_id"].(string)),
434+
}
435+
436+
return encryption
437+
}
438+
439+
func flattenMachineLearningWorkspaceEncryption(encryption *machinelearningservices.EncryptionProperty) []interface{} {
440+
if encryption == nil {
441+
return []interface{}{}
442+
}
443+
444+
return []interface{}{
445+
map[string]interface{}{
446+
"key_vault_id": *encryption.KeyVaultProperties.KeyVaultArmID,
447+
"key_id": *encryption.KeyVaultProperties.KeyIdentifier,
448+
},
449+
}
450+
}

internal/services/machinelearning/machine_learning_workspace_resource_test.go

+65-1
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,24 @@ resource "azurerm_container_registry" "test" {
209209
admin_enabled = true
210210
}
211211
212+
resource "azurerm_key_vault_key" "test" {
213+
name = "acctest-kv-key-%[2]d"
214+
key_vault_id = azurerm_key_vault.test.id
215+
key_type = "RSA"
216+
key_size = 2048
217+
218+
key_opts = [
219+
"decrypt",
220+
"encrypt",
221+
"sign",
222+
"unwrapKey",
223+
"verify",
224+
"wrapKey",
225+
]
226+
227+
depends_on = [azurerm_key_vault.test, azurerm_key_vault_access_policy.test]
228+
}
229+
212230
resource "azurerm_machine_learning_workspace" "test" {
213231
name = "acctest-MLW-%[2]d"
214232
location = azurerm_resource_group.test.location
@@ -228,6 +246,12 @@ resource "azurerm_machine_learning_workspace" "test" {
228246
type = "SystemAssigned"
229247
}
230248
249+
encryption {
250+
key_vault_id = azurerm_key_vault.test.id
251+
key_id = azurerm_key_vault_key.test.id
252+
}
253+
254+
231255
tags = {
232256
ENV = "Test"
233257
}
@@ -248,6 +272,24 @@ resource "azurerm_container_registry" "test" {
248272
admin_enabled = true
249273
}
250274
275+
resource "azurerm_key_vault_key" "test" {
276+
name = "acctest-kv-key-%[2]d"
277+
key_vault_id = azurerm_key_vault.test.id
278+
key_type = "RSA"
279+
key_size = 2048
280+
281+
key_opts = [
282+
"decrypt",
283+
"encrypt",
284+
"sign",
285+
"unwrapKey",
286+
"verify",
287+
"wrapKey",
288+
]
289+
290+
depends_on = [azurerm_key_vault.test, azurerm_key_vault_access_policy.test]
291+
}
292+
251293
resource "azurerm_machine_learning_workspace" "test" {
252294
name = "acctest-MLW-%[2]d"
253295
location = azurerm_resource_group.test.location
@@ -267,6 +309,11 @@ resource "azurerm_machine_learning_workspace" "test" {
267309
type = "SystemAssigned"
268310
}
269311
312+
encryption {
313+
key_vault_id = azurerm_key_vault.test.id
314+
key_id = azurerm_key_vault_key.test.id
315+
}
316+
270317
tags = {
271318
ENV = "Test"
272319
FOO = "Updated"
@@ -298,7 +345,11 @@ resource "azurerm_machine_learning_workspace" "import" {
298345
func (r WorkspaceResource) template(data acceptance.TestData) string {
299346
return fmt.Sprintf(`
300347
provider "azurerm" {
301-
features {}
348+
features {
349+
key_vault {
350+
purge_soft_delete_on_destroy = false
351+
}
352+
}
302353
}
303354
304355
data "azurerm_client_config" "current" {}
@@ -326,6 +377,19 @@ resource "azurerm_key_vault" "test" {
326377
purge_protection_enabled = true
327378
}
328379
380+
resource "azurerm_key_vault_access_policy" "test" {
381+
key_vault_id = azurerm_key_vault.test.id
382+
tenant_id = data.azurerm_client_config.current.tenant_id
383+
object_id = data.azurerm_client_config.current.object_id
384+
385+
key_permissions = [
386+
"Create",
387+
"Get",
388+
"Delete",
389+
"Purge",
390+
]
391+
}
392+
329393
resource "azurerm_storage_account" "test" {
330394
name = "acctestsa%[4]d"
331395
location = azurerm_resource_group.test.location

website/docs/r/machine_learning_workspace.html.markdown

+101
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,99 @@ resource "azurerm_machine_learning_workspace" "example" {
6060
}
6161
```
6262

63+
## Example Usage with Data encryption
64+
65+
~> **NOTE:** The Key Vault must enable purge protection.
66+
67+
```hcl
68+
provider "azurerm" {
69+
features {
70+
key_vault {
71+
purge_soft_delete_on_destroy = false
72+
}
73+
}
74+
}
75+
76+
data "azurerm_client_config" "current" {}
77+
78+
resource "azurerm_resource_group" "example" {
79+
name = "example-resources"
80+
location = "West Europe"
81+
}
82+
83+
resource "azurerm_application_insights" "example" {
84+
name = "workspace-example-ai"
85+
location = azurerm_resource_group.example.location
86+
resource_group_name = azurerm_resource_group.example.name
87+
application_type = "web"
88+
}
89+
90+
resource "azurerm_key_vault" "example" {
91+
name = "workspaceexamplekeyvault"
92+
location = azurerm_resource_group.example.location
93+
resource_group_name = azurerm_resource_group.example.name
94+
tenant_id = data.azurerm_client_config.current.tenant_id
95+
sku_name = "premium"
96+
purge_protection_enabled = true
97+
}
98+
resource "azurerm_key_vault_access_policy" "example" {
99+
key_vault_id = azurerm_key_vault.example.id
100+
tenant_id = data.azurerm_client_config.current.tenant_id
101+
object_id = data.azurerm_client_config.current.object_id
102+
103+
key_permissions = [
104+
"Create",
105+
"Get",
106+
"Delete",
107+
"Purge",
108+
]
109+
}
110+
111+
resource "azurerm_storage_account" "example" {
112+
name = "workspacestorageaccount"
113+
location = azurerm_resource_group.example.location
114+
resource_group_name = azurerm_resource_group.example.name
115+
account_tier = "Standard"
116+
account_replication_type = "GRS"
117+
}
118+
119+
resource "azurerm_key_vault_key" "example" {
120+
name = "workspaceexamplekeyvaultkey"
121+
key_vault_id = azurerm_key_vault.example.id
122+
key_type = "RSA"
123+
key_size = 2048
124+
125+
key_opts = [
126+
"decrypt",
127+
"encrypt",
128+
"sign",
129+
"unwrapKey",
130+
"verify",
131+
"wrapKey",
132+
]
133+
134+
depends_on = [azurerm_key_vault.example, azurerm_key_vault_access_policy.example]
135+
}
136+
137+
resource "azurerm_machine_learning_workspace" "example" {
138+
name = "example-workspace"
139+
location = azurerm_resource_group.example.location
140+
resource_group_name = azurerm_resource_group.example.name
141+
application_insights_id = azurerm_application_insights.example.id
142+
key_vault_id = azurerm_key_vault.example.id
143+
storage_account_id = azurerm_storage_account.example.id
144+
145+
identity {
146+
type = "SystemAssigned"
147+
}
148+
149+
encryption {
150+
key_vault_id = azurerm_key_vault.example.id
151+
key_id = azurerm_key_vault_key.example.id
152+
}
153+
}
154+
```
155+
63156
## Argument Reference
64157

65158
The following arguments are supported:
@@ -108,6 +201,14 @@ An `identity` block supports the following:
108201

109202
* `type` - (Required) The Type of Identity which should be used for this Disk Encryption Set. At this time the only possible value is `SystemAssigned`.
110203

204+
---
205+
206+
An `encryption` block supports the following:
207+
208+
* `key_vault_id` - (Required) The ID of the keyVault where the customer owned encryption key is present.
209+
210+
* `key_id` - (Required) The Key Vault URI to access the encryption key.
211+
111212
## Attributes Reference
112213

113214
The following attributes are exported:

0 commit comments

Comments
 (0)