diff --git a/.changelog/4425.txt b/.changelog/4425.txt new file mode 100644 index 00000000000..48ab6e25c03 --- /dev/null +++ b/.changelog/4425.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +notebooks: added `tags`, `service_account_scopes`,`shielded_instance_config` to `google_notebooks_instance` +``` diff --git a/google/resource_notebooks_instance.go b/google/resource_notebooks_instance.go index 2b7d19ca99b..62a21c6a77c 100644 --- a/google/resource_notebooks_instance.go +++ b/google/resource_notebooks_instance.go @@ -83,8 +83,8 @@ machineType you have selected.`, Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: validation.StringInSlice([]string{"ACCELERATOR_TYPE_UNSPECIFIED", "NVIDIA_TESLA_K80", "NVIDIA_TESLA_P100", "NVIDIA_TESLA_V100", "NVIDIA_TESLA_P4", "NVIDIA_TESLA_T4", "NVIDIA_TESLA_T4_VWS", "NVIDIA_TESLA_P100_VWS", "NVIDIA_TESLA_P4_VWS", "TPU_V2", "TPU_V3"}, false), - Description: `Type of this accelerator. Possible values: ["ACCELERATOR_TYPE_UNSPECIFIED", "NVIDIA_TESLA_K80", "NVIDIA_TESLA_P100", "NVIDIA_TESLA_V100", "NVIDIA_TESLA_P4", "NVIDIA_TESLA_T4", "NVIDIA_TESLA_T4_VWS", "NVIDIA_TESLA_P100_VWS", "NVIDIA_TESLA_P4_VWS", "TPU_V2", "TPU_V3"]`, + ValidateFunc: validation.StringInSlice([]string{"ACCELERATOR_TYPE_UNSPECIFIED", "NVIDIA_TESLA_K80", "NVIDIA_TESLA_P100", "NVIDIA_TESLA_V100", "NVIDIA_TESLA_P4", "NVIDIA_TESLA_T4", "NVIDIA_TESLA_T4_VWS", "NVIDIA_TESLA_P100_VWS", "NVIDIA_TESLA_P4_VWS", "NVIDIA_TESLA_A100", "TPU_V2", "TPU_V3"}, false), + Description: `Type of this accelerator. Possible values: ["ACCELERATOR_TYPE_UNSPECIFIED", "NVIDIA_TESLA_K80", "NVIDIA_TESLA_P100", "NVIDIA_TESLA_V100", "NVIDIA_TESLA_P4", "NVIDIA_TESLA_T4", "NVIDIA_TESLA_T4_VWS", "NVIDIA_TESLA_P100_VWS", "NVIDIA_TESLA_P4_VWS", "NVIDIA_TESLA_A100", "TPU_V2", "TPU_V3"]`, }, }, }, @@ -217,13 +217,13 @@ Format: projects/{project_id}/global/networks/{network_id}`, Type: schema.TypeBool, Optional: true, ForceNew: true, - Description: `the notebook instance will not register with the proxy..`, + Description: `The notebook instance will not register with the proxy..`, }, "no_public_ip": { Type: schema.TypeBool, Optional: true, ForceNew: true, - Description: `no public IP will be assigned to this instance.`, + Description: `No public IP will be assigned to this instance.`, }, "no_remove_data_disk": { Type: schema.TypeBool, @@ -250,6 +250,58 @@ the same project, but you must have the service account user permission to use the instance. If not specified, the Compute Engine default service account is used.`, }, + "service_account_scopes": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Optional. The URIs of service account scopes to be included in Compute Engine instances. +If not specified, the following scopes are defined: +- https://www.googleapis.com/auth/cloud-platform +- https://www.googleapis.com/auth/userinfo.email`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "shielded_instance_config": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `A set of Shielded Instance options. Check [Images using supported Shielded VM features] +Not all combinations are valid`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enable_integrity_monitoring": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Description: `Defines whether the instance has integrity monitoring enabled. Enables monitoring and attestation of the +boot integrity of the instance. The attestation is performed against the integrity policy baseline. +This baseline is initially derived from the implicitly trusted boot image when the instance is created. +Enabled by default.`, + Default: true, + }, + "enable_secure_boot": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Description: `Defines whether the instance has Secure Boot enabled. Secure Boot helps ensure that the system only runs +authentic software by verifying the digital signature of all boot components, and halting the boot process +if signature verification fails. +Disabled by default.`, + }, + "enable_vtpm": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Description: `Defines whether the instance has the vTPM enabled. +Enabled by default.`, + Default: true, + }, + }, + }, + }, "subnet": { Type: schema.TypeString, Computed: true, @@ -259,6 +311,15 @@ the Compute Engine default service account is used.`, Description: `The name of the subnet that this instance is in. Format: projects/{project_id}/regions/{region}/subnetworks/{subnetwork_id}`, }, + "tags": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `The Compute Engine tags to add to runtime.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, "vm_image": { Type: schema.TypeList, Optional: true, @@ -355,12 +416,24 @@ func resourceNotebooksInstanceCreate(d *schema.ResourceData, meta interface{}) e } else if v, ok := d.GetOkExists("service_account"); !isEmptyValue(reflect.ValueOf(serviceAccountProp)) && (ok || !reflect.DeepEqual(v, serviceAccountProp)) { obj["serviceAccount"] = serviceAccountProp } + serviceAccountScopesProp, err := expandNotebooksInstanceServiceAccountScopes(d.Get("service_account_scopes"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("service_account_scopes"); !isEmptyValue(reflect.ValueOf(serviceAccountScopesProp)) && (ok || !reflect.DeepEqual(v, serviceAccountScopesProp)) { + obj["serviceAccountScopes"] = serviceAccountScopesProp + } acceleratorConfigProp, err := expandNotebooksInstanceAcceleratorConfig(d.Get("accelerator_config"), d, config) if err != nil { return err } else if v, ok := d.GetOkExists("accelerator_config"); !isEmptyValue(reflect.ValueOf(acceleratorConfigProp)) && (ok || !reflect.DeepEqual(v, acceleratorConfigProp)) { obj["acceleratorConfig"] = acceleratorConfigProp } + shieldedInstanceConfigProp, err := expandNotebooksInstanceShieldedInstanceConfig(d.Get("shielded_instance_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("shielded_instance_config"); !isEmptyValue(reflect.ValueOf(shieldedInstanceConfigProp)) && (ok || !reflect.DeepEqual(v, shieldedInstanceConfigProp)) { + obj["shieldedInstanceConfig"] = shieldedInstanceConfigProp + } installGpuDriverProp, err := expandNotebooksInstanceInstallGpuDriver(d.Get("install_gpu_driver"), d, config) if err != nil { return err @@ -445,6 +518,12 @@ func resourceNotebooksInstanceCreate(d *schema.ResourceData, meta interface{}) e } else if v, ok := d.GetOkExists("labels"); !isEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { obj["labels"] = labelsProp } + tagsProp, err := expandNotebooksInstanceTags(d.Get("tags"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("tags"); !isEmptyValue(reflect.ValueOf(tagsProp)) && (ok || !reflect.DeepEqual(v, tagsProp)) { + obj["tags"] = tagsProp + } metadataProp, err := expandNotebooksInstanceMetadata(d.Get("metadata"), d, config) if err != nil { return err @@ -565,9 +644,15 @@ func resourceNotebooksInstanceRead(d *schema.ResourceData, meta interface{}) err if err := d.Set("service_account", flattenNotebooksInstanceServiceAccount(res["serviceAccount"], d, config)); err != nil { return fmt.Errorf("Error reading Instance: %s", err) } + if err := d.Set("service_account_scopes", flattenNotebooksInstanceServiceAccountScopes(res["serviceAccountScopes"], d, config)); err != nil { + return fmt.Errorf("Error reading Instance: %s", err) + } if err := d.Set("accelerator_config", flattenNotebooksInstanceAcceleratorConfig(res["acceleratorConfig"], d, config)); err != nil { return fmt.Errorf("Error reading Instance: %s", err) } + if err := d.Set("shielded_instance_config", flattenNotebooksInstanceShieldedInstanceConfig(res["shieldedInstanceConfig"], d, config)); err != nil { + return fmt.Errorf("Error reading Instance: %s", err) + } if err := d.Set("state", flattenNotebooksInstanceState(res["state"], d, config)); err != nil { return fmt.Errorf("Error reading Instance: %s", err) } @@ -601,6 +686,9 @@ func resourceNotebooksInstanceRead(d *schema.ResourceData, meta interface{}) err if err := d.Set("labels", flattenNotebooksInstanceLabels(res["labels"], d, config)); err != nil { return fmt.Errorf("Error reading Instance: %s", err) } + if err := d.Set("tags", flattenNotebooksInstanceTags(res["tags"], d, config)); err != nil { + return fmt.Errorf("Error reading Instance: %s", err) + } if err := d.Set("create_time", flattenNotebooksInstanceCreateTime(res["createTime"], d, config)); err != nil { return fmt.Errorf("Error reading Instance: %s", err) } @@ -752,6 +840,10 @@ func flattenNotebooksInstanceServiceAccount(v interface{}, d *schema.ResourceDat return v } +func flattenNotebooksInstanceServiceAccountScopes(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + func flattenNotebooksInstanceAcceleratorConfig(v interface{}, d *schema.ResourceData, config *Config) interface{} { if v == nil { return nil @@ -788,6 +880,35 @@ func flattenNotebooksInstanceAcceleratorConfigCoreCount(v interface{}, d *schema return v // let terraform core handle it otherwise } +func flattenNotebooksInstanceShieldedInstanceConfig(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["enable_integrity_monitoring"] = + flattenNotebooksInstanceShieldedInstanceConfigEnableIntegrityMonitoring(original["enableIntegrityMonitoring"], d, config) + transformed["enable_secure_boot"] = + flattenNotebooksInstanceShieldedInstanceConfigEnableSecureBoot(original["enableSecureBoot"], d, config) + transformed["enable_vtpm"] = + flattenNotebooksInstanceShieldedInstanceConfigEnableVtpm(original["enableVtpm"], d, config) + return []interface{}{transformed} +} +func flattenNotebooksInstanceShieldedInstanceConfigEnableIntegrityMonitoring(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenNotebooksInstanceShieldedInstanceConfigEnableSecureBoot(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenNotebooksInstanceShieldedInstanceConfigEnableVtpm(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + func flattenNotebooksInstanceState(v interface{}, d *schema.ResourceData, config *Config) interface{} { return v } @@ -832,6 +953,10 @@ func flattenNotebooksInstanceLabels(v interface{}, d *schema.ResourceData, confi return v } +func flattenNotebooksInstanceTags(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + func flattenNotebooksInstanceCreateTime(v interface{}, d *schema.ResourceData, config *Config) interface{} { return v } @@ -856,6 +981,10 @@ func expandNotebooksInstanceServiceAccount(v interface{}, d TerraformResourceDat return v, nil } +func expandNotebooksInstanceServiceAccountScopes(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + func expandNotebooksInstanceAcceleratorConfig(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { l := v.([]interface{}) if len(l) == 0 || l[0] == nil { @@ -890,6 +1019,51 @@ func expandNotebooksInstanceAcceleratorConfigCoreCount(v interface{}, d Terrafor return v, nil } +func expandNotebooksInstanceShieldedInstanceConfig(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedEnableIntegrityMonitoring, err := expandNotebooksInstanceShieldedInstanceConfigEnableIntegrityMonitoring(original["enable_integrity_monitoring"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEnableIntegrityMonitoring); val.IsValid() && !isEmptyValue(val) { + transformed["enableIntegrityMonitoring"] = transformedEnableIntegrityMonitoring + } + + transformedEnableSecureBoot, err := expandNotebooksInstanceShieldedInstanceConfigEnableSecureBoot(original["enable_secure_boot"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEnableSecureBoot); val.IsValid() && !isEmptyValue(val) { + transformed["enableSecureBoot"] = transformedEnableSecureBoot + } + + transformedEnableVtpm, err := expandNotebooksInstanceShieldedInstanceConfigEnableVtpm(original["enable_vtpm"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEnableVtpm); val.IsValid() && !isEmptyValue(val) { + transformed["enableVtpm"] = transformedEnableVtpm + } + + return transformed, nil +} + +func expandNotebooksInstanceShieldedInstanceConfigEnableIntegrityMonitoring(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandNotebooksInstanceShieldedInstanceConfigEnableSecureBoot(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandNotebooksInstanceShieldedInstanceConfigEnableVtpm(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + func expandNotebooksInstanceInstallGpuDriver(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { return v, nil } @@ -953,6 +1127,10 @@ func expandNotebooksInstanceLabels(v interface{}, d TerraformResourceData, confi return m, nil } +func expandNotebooksInstanceTags(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + func expandNotebooksInstanceMetadata(v interface{}, d TerraformResourceData, config *Config) (map[string]string, error) { if v == nil { return map[string]string{}, nil diff --git a/website/docs/r/notebooks_instance.html.markdown b/website/docs/r/notebooks_instance.html.markdown index 6fe913a507c..7e18d1032ad 100644 --- a/website/docs/r/notebooks_instance.html.markdown +++ b/website/docs/r/notebooks_instance.html.markdown @@ -199,6 +199,13 @@ The following arguments are supported: permission to use the instance. If not specified, the Compute Engine default service account is used. +* `service_account_scopes` - + (Optional) + Optional. The URIs of service account scopes to be included in Compute Engine instances. + If not specified, the following scopes are defined: + - https://www.googleapis.com/auth/cloud-platform + - https://www.googleapis.com/auth/userinfo.email + * `accelerator_config` - (Optional) The hardware accelerator used on this instance. If you use accelerators, @@ -206,6 +213,12 @@ The following arguments are supported: machineType you have selected. Structure is documented below. +* `shielded_instance_config` - + (Optional) + A set of Shielded Instance options. Check [Images using supported Shielded VM features] + Not all combinations are valid + Structure is documented below. + * `install_gpu_driver` - (Optional) Whether the end user authorizes Google Cloud to install GPU driver @@ -256,11 +269,11 @@ The following arguments are supported: * `no_public_ip` - (Optional) - no public IP will be assigned to this instance. + No public IP will be assigned to this instance. * `no_proxy_access` - (Optional) - the notebook instance will not register with the proxy.. + The notebook instance will not register with the proxy.. * `network` - (Optional) @@ -277,6 +290,10 @@ The following arguments are supported: Labels to apply to this instance. These can be later modified by the setLabels method. An object containing a list of "key": value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }. +* `tags` - + (Optional) + The Compute Engine tags to add to runtime. + * `metadata` - (Optional) Custom metadata to apply to this instance. @@ -301,12 +318,33 @@ The `accelerator_config` block supports: * `type` - (Required) Type of this accelerator. - Possible values are `ACCELERATOR_TYPE_UNSPECIFIED`, `NVIDIA_TESLA_K80`, `NVIDIA_TESLA_P100`, `NVIDIA_TESLA_V100`, `NVIDIA_TESLA_P4`, `NVIDIA_TESLA_T4`, `NVIDIA_TESLA_T4_VWS`, `NVIDIA_TESLA_P100_VWS`, `NVIDIA_TESLA_P4_VWS`, `TPU_V2`, and `TPU_V3`. + Possible values are `ACCELERATOR_TYPE_UNSPECIFIED`, `NVIDIA_TESLA_K80`, `NVIDIA_TESLA_P100`, `NVIDIA_TESLA_V100`, `NVIDIA_TESLA_P4`, `NVIDIA_TESLA_T4`, `NVIDIA_TESLA_T4_VWS`, `NVIDIA_TESLA_P100_VWS`, `NVIDIA_TESLA_P4_VWS`, `NVIDIA_TESLA_A100`, `TPU_V2`, and `TPU_V3`. * `core_count` - (Required) Count of cores of this accelerator. +The `shielded_instance_config` block supports: + +* `enable_integrity_monitoring` - + (Optional) + Defines whether the instance has integrity monitoring enabled. Enables monitoring and attestation of the + boot integrity of the instance. The attestation is performed against the integrity policy baseline. + This baseline is initially derived from the implicitly trusted boot image when the instance is created. + Enabled by default. + +* `enable_secure_boot` - + (Optional) + Defines whether the instance has Secure Boot enabled. Secure Boot helps ensure that the system only runs + authentic software by verifying the digital signature of all boot components, and halting the boot process + if signature verification fails. + Disabled by default. + +* `enable_vtpm` - + (Optional) + Defines whether the instance has the vTPM enabled. + Enabled by default. + The `vm_image` block supports: * `project` -