Skip to content

Commit 78efc1d

Browse files
update for support of CMEK for vertex ai resource (#6460) (#4643)
* update for support of CMEK for vertex ai resource * kms key as a resource added * Bootstrapped kms-key-name Signed-off-by: Modular Magician <[email protected]> Signed-off-by: Modular Magician <[email protected]>
1 parent fe7e660 commit 78efc1d

10 files changed

+112
-16
lines changed

.changelog/6460.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
vertexai: added `encryption_spec` field to `google_vertex_ai_featurestore` resource (beta)
3+
```

google-beta/resource_vertex_ai_dataset.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func resourceVertexAIDataset() *schema.Resource {
6161
Type: schema.TypeString,
6262
Optional: true,
6363
ForceNew: true,
64-
Description: `Required. The Cloud KMS resource identifier of the customer managed encryption key used to protect a resource.
64+
Description: `Required. The Cloud KMS resource identifier of the customer managed encryption key used to protect a resource.
6565
Has the form: projects/my-project/locations/my-region/keyRings/my-kr/cryptoKeys/my-key. The key needs to be in the same region as where the resource is created.`,
6666
},
6767
},

google-beta/resource_vertex_ai_featurestore.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,21 @@ func resourceVertexAIFeaturestore() *schema.Resource {
4242
},
4343

4444
Schema: map[string]*schema.Schema{
45+
"encryption_spec": {
46+
Type: schema.TypeList,
47+
Optional: true,
48+
Description: `If set, both of the online and offline data storage will be secured by this key.`,
49+
MaxItems: 1,
50+
Elem: &schema.Resource{
51+
Schema: map[string]*schema.Schema{
52+
"kms_key_name": {
53+
Type: schema.TypeString,
54+
Required: true,
55+
Description: `The Cloud KMS resource identifier of the customer managed encryption key used to protect a resource. Has the form: projects/my-project/locations/my-region/keyRings/my-kr/cryptoKeys/my-key. The key needs to be in the same region as where the compute resource is created.`,
56+
},
57+
},
58+
},
59+
},
4560
"labels": {
4661
Type: schema.TypeMap,
4762
Optional: true,
@@ -127,6 +142,12 @@ func resourceVertexAIFeaturestoreCreate(d *schema.ResourceData, meta interface{}
127142
} else if v, ok := d.GetOkExists("online_serving_config"); !isEmptyValue(reflect.ValueOf(onlineServingConfigProp)) && (ok || !reflect.DeepEqual(v, onlineServingConfigProp)) {
128143
obj["onlineServingConfig"] = onlineServingConfigProp
129144
}
145+
encryptionSpecProp, err := expandVertexAIFeaturestoreEncryptionSpec(d.Get("encryption_spec"), d, config)
146+
if err != nil {
147+
return err
148+
} else if v, ok := d.GetOkExists("encryption_spec"); !isEmptyValue(reflect.ValueOf(encryptionSpecProp)) && (ok || !reflect.DeepEqual(v, encryptionSpecProp)) {
149+
obj["encryptionSpec"] = encryptionSpecProp
150+
}
130151

131152
url, err := replaceVars(d, config, "{{VertexAIBasePath}}projects/{{project}}/locations/{{region}}/featurestores?featurestoreId={{name}}")
132153
if err != nil {
@@ -235,6 +256,9 @@ func resourceVertexAIFeaturestoreRead(d *schema.ResourceData, meta interface{})
235256
if err := d.Set("online_serving_config", flattenVertexAIFeaturestoreOnlineServingConfig(res["onlineServingConfig"], d, config)); err != nil {
236257
return fmt.Errorf("Error reading Featurestore: %s", err)
237258
}
259+
if err := d.Set("encryption_spec", flattenVertexAIFeaturestoreEncryptionSpec(res["encryptionSpec"], d, config)); err != nil {
260+
return fmt.Errorf("Error reading Featurestore: %s", err)
261+
}
238262

239263
return nil
240264
}
@@ -267,6 +291,12 @@ func resourceVertexAIFeaturestoreUpdate(d *schema.ResourceData, meta interface{}
267291
} else if v, ok := d.GetOkExists("online_serving_config"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, onlineServingConfigProp)) {
268292
obj["onlineServingConfig"] = onlineServingConfigProp
269293
}
294+
encryptionSpecProp, err := expandVertexAIFeaturestoreEncryptionSpec(d.Get("encryption_spec"), d, config)
295+
if err != nil {
296+
return err
297+
} else if v, ok := d.GetOkExists("encryption_spec"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, encryptionSpecProp)) {
298+
obj["encryptionSpec"] = encryptionSpecProp
299+
}
270300

271301
url, err := replaceVars(d, config, "{{VertexAIBasePath}}projects/{{project}}/locations/{{region}}/featurestores/{{name}}")
272302
if err != nil {
@@ -283,6 +313,10 @@ func resourceVertexAIFeaturestoreUpdate(d *schema.ResourceData, meta interface{}
283313
if d.HasChange("online_serving_config") {
284314
updateMask = append(updateMask, "onlineServingConfig")
285315
}
316+
317+
if d.HasChange("encryption_spec") {
318+
updateMask = append(updateMask, "encryptionSpec")
319+
}
286320
// updateMask is a URL parameter but not present in the schema, so replaceVars
287321
// won't set it
288322
url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
@@ -434,6 +468,23 @@ func flattenVertexAIFeaturestoreOnlineServingConfigFixedNodeCount(v interface{},
434468
return v // let terraform core handle it otherwise
435469
}
436470

471+
func flattenVertexAIFeaturestoreEncryptionSpec(v interface{}, d *schema.ResourceData, config *Config) interface{} {
472+
if v == nil {
473+
return nil
474+
}
475+
original := v.(map[string]interface{})
476+
if len(original) == 0 {
477+
return nil
478+
}
479+
transformed := make(map[string]interface{})
480+
transformed["kms_key_name"] =
481+
flattenVertexAIFeaturestoreEncryptionSpecKmsKeyName(original["kmsKeyName"], d, config)
482+
return []interface{}{transformed}
483+
}
484+
func flattenVertexAIFeaturestoreEncryptionSpecKmsKeyName(v interface{}, d *schema.ResourceData, config *Config) interface{} {
485+
return v
486+
}
487+
437488
func expandVertexAIFeaturestoreLabels(v interface{}, d TerraformResourceData, config *Config) (map[string]string, error) {
438489
if v == nil {
439490
return map[string]string{}, nil
@@ -467,3 +518,26 @@ func expandVertexAIFeaturestoreOnlineServingConfig(v interface{}, d TerraformRes
467518
func expandVertexAIFeaturestoreOnlineServingConfigFixedNodeCount(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
468519
return v, nil
469520
}
521+
522+
func expandVertexAIFeaturestoreEncryptionSpec(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
523+
l := v.([]interface{})
524+
if len(l) == 0 || l[0] == nil {
525+
return nil, nil
526+
}
527+
raw := l[0]
528+
original := raw.(map[string]interface{})
529+
transformed := make(map[string]interface{})
530+
531+
transformedKmsKeyName, err := expandVertexAIFeaturestoreEncryptionSpecKmsKeyName(original["kms_key_name"], d, config)
532+
if err != nil {
533+
return nil, err
534+
} else if val := reflect.ValueOf(transformedKmsKeyName); val.IsValid() && !isEmptyValue(val) {
535+
transformed["kmsKeyName"] = transformedKmsKeyName
536+
}
537+
538+
return transformed, nil
539+
}
540+
541+
func expandVertexAIFeaturestoreEncryptionSpecKmsKeyName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
542+
return v, nil
543+
}

google-beta/resource_vertex_ai_featurestore_entitytype_generated_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ func TestAccVertexAIFeaturestoreEntitytype_vertexAiFeaturestoreEntitytypeExample
2727
t.Parallel()
2828

2929
context := map[string]interface{}{
30-
"random_suffix": randString(t, 10),
30+
"org_id": getTestOrgFromEnv(t),
31+
"billing_account": getTestBillingAccountFromEnv(t),
32+
"kms_key_name": BootstrapKMSKeyInLocation(t, "us-central1").CryptoKey.Name,
33+
"random_suffix": randString(t, 10),
3134
}
3235

3336
vcrTest(t, resource.TestCase{
@@ -60,6 +63,9 @@ resource "google_vertex_ai_featurestore" "featurestore" {
6063
online_serving_config {
6164
fixed_node_count = 2
6265
}
66+
encryption_spec {
67+
kms_key_name = "%{kms_key_name}"
68+
}
6369
}
6470
6571
resource "google_vertex_ai_featurestore_entitytype" "entity" {

google-beta/resource_vertex_ai_featurestore_generated_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ func TestAccVertexAIFeaturestore_vertexAiFeaturestoreExample(t *testing.T) {
2727
t.Parallel()
2828

2929
context := map[string]interface{}{
30-
"random_suffix": randString(t, 10),
30+
"org_id": getTestOrgFromEnv(t),
31+
"billing_account": getTestBillingAccountFromEnv(t),
32+
"kms_key_name": BootstrapKMSKeyInLocation(t, "us-central1").CryptoKey.Name,
33+
"random_suffix": randString(t, 10),
3134
}
3235

3336
vcrTest(t, resource.TestCase{
@@ -60,6 +63,9 @@ resource "google_vertex_ai_featurestore" "featurestore" {
6063
online_serving_config {
6164
fixed_node_count = 2
6265
}
66+
encryption_spec {
67+
kms_key_name = "%{kms_key_name}"
68+
}
6369
force_destroy = true
6470
}
6571
`, context)

google-beta/resource_vertex_ai_metadata_store.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func resourceVertexAIMetadataStore() *schema.Resource {
5757
Type: schema.TypeString,
5858
Optional: true,
5959
ForceNew: true,
60-
Description: `Required. The Cloud KMS resource identifier of the customer managed encryption key used to protect a resource.
60+
Description: `Required. The Cloud KMS resource identifier of the customer managed encryption key used to protect a resource.
6161
Has the form: projects/my-project/locations/my-region/keyRings/my-kr/cryptoKeys/my-key. The key needs to be in the same region as where the resource is created.`,
6262
},
6363
},

website/docs/r/vertex_ai_dataset.html.markdown

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ The following arguments are supported:
8383

8484
* `kms_key_name` -
8585
(Optional)
86-
Required. The Cloud KMS resource identifier of the customer managed encryption key used to protect a resource.
86+
Required. The Cloud KMS resource identifier of the customer managed encryption key used to protect a resource.
8787
Has the form: projects/my-project/locations/my-region/keyRings/my-kr/cryptoKeys/my-key. The key needs to be in the same region as where the resource is created.
8888

8989
## Attributes Reference

website/docs/r/vertex_ai_featurestore.html.markdown

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,6 @@ To get more information about Featurestore, see:
3131
* How-to Guides
3232
* [Official Documentation](https://cloud.google.com/vertex-ai/docs)
3333

34-
<div class = "oics-button" style="float: right; margin: 0 0 -15px">
35-
<a href="https://console.cloud.google.com/cloudshell/open?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fterraform-google-modules%2Fdocs-examples.git&cloudshell_working_dir=vertex_ai_featurestore&cloudshell_image=gcr.io%2Fgraphite-cloud-shell-images%2Fterraform%3Alatest&open_in_editor=main.tf&cloudshell_print=.%2Fmotd&cloudshell_tutorial=.%2Ftutorial.md" target="_blank">
36-
<img alt="Open in Cloud Shell" src="//gstatic.com/cloudssh/images/open-btn.svg" style="max-height: 44px; margin: 32px auto; max-width: 100%;">
37-
</a>
38-
</div>
3934
## Example Usage - Vertex Ai Featurestore
4035

4136

@@ -50,6 +45,9 @@ resource "google_vertex_ai_featurestore" "featurestore" {
5045
online_serving_config {
5146
fixed_node_count = 2
5247
}
48+
encryption_spec {
49+
kms_key_name = "kms-name"
50+
}
5351
force_destroy = true
5452
}
5553
```
@@ -76,6 +74,11 @@ The following arguments are supported:
7674
Config for online serving resources.
7775
Structure is [documented below](#nested_online_serving_config).
7876

77+
* `encryption_spec` -
78+
(Optional)
79+
If set, both of the online and offline data storage will be secured by this key.
80+
Structure is [documented below](#nested_encryption_spec).
81+
7982
* `region` -
8083
(Optional)
8184
The region of the dataset. eg us-central1
@@ -91,6 +94,12 @@ The following arguments are supported:
9194
(Required)
9295
The number of nodes for each cluster. The number of nodes will not scale automatically but can be scaled manually by providing different values when updating.
9396

97+
<a name="nested_encryption_spec"></a>The `encryption_spec` block supports:
98+
99+
* `kms_key_name` -
100+
(Required)
101+
The Cloud KMS resource identifier of the customer managed encryption key used to protect a resource. Has the form: projects/my-project/locations/my-region/keyRings/my-kr/cryptoKeys/my-key. The key needs to be in the same region as where the compute resource is created.
102+
94103
## Attributes Reference
95104

96105
In addition to the arguments listed above, the following computed attributes are exported:

website/docs/r/vertex_ai_featurestore_entitytype.html.markdown

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,6 @@ To get more information about FeaturestoreEntitytype, see:
3131
* How-to Guides
3232
* [Official Documentation](https://cloud.google.com/vertex-ai/docs)
3333

34-
<div class = "oics-button" style="float: right; margin: 0 0 -15px">
35-
<a href="https://console.cloud.google.com/cloudshell/open?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fterraform-google-modules%2Fdocs-examples.git&cloudshell_working_dir=vertex_ai_featurestore_entitytype&cloudshell_image=gcr.io%2Fgraphite-cloud-shell-images%2Fterraform%3Alatest&open_in_editor=main.tf&cloudshell_print=.%2Fmotd&cloudshell_tutorial=.%2Ftutorial.md" target="_blank">
36-
<img alt="Open in Cloud Shell" src="//gstatic.com/cloudssh/images/open-btn.svg" style="max-height: 44px; margin: 32px auto; max-width: 100%;">
37-
</a>
38-
</div>
3934
## Example Usage - Vertex Ai Featurestore Entitytype
4035

4136

@@ -50,6 +45,9 @@ resource "google_vertex_ai_featurestore" "featurestore" {
5045
online_serving_config {
5146
fixed_node_count = 2
5247
}
48+
encryption_spec {
49+
kms_key_name = "kms-name"
50+
}
5351
}
5452
5553
resource "google_vertex_ai_featurestore_entitytype" "entity" {

website/docs/r/vertex_ai_metadata_store.html.markdown

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ The following arguments are supported:
7676

7777
* `kms_key_name` -
7878
(Optional)
79-
Required. The Cloud KMS resource identifier of the customer managed encryption key used to protect a resource.
79+
Required. The Cloud KMS resource identifier of the customer managed encryption key used to protect a resource.
8080
Has the form: projects/my-project/locations/my-region/keyRings/my-kr/cryptoKeys/my-key. The key needs to be in the same region as where the resource is created.
8181

8282
## Attributes Reference

0 commit comments

Comments
 (0)