diff --git a/.changelog/9973.txt b/.changelog/9973.txt new file mode 100644 index 00000000000..2d62ba8cae4 --- /dev/null +++ b/.changelog/9973.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +workbench: added `container_image` field to `google_workbench_instance` resource +``` \ No newline at end of file diff --git a/google/services/workbench/resource_workbench_instance.go b/google/services/workbench/resource_workbench_instance.go index 79467391853..c71e8f97e9c 100644 --- a/google/services/workbench/resource_workbench_instance.go +++ b/google/services/workbench/resource_workbench_instance.go @@ -328,6 +328,28 @@ Learn more about using your own encryption keys.'`, }, }, }, + "container_image": { + Type: schema.TypeList, + Optional: true, + Description: `Use a container image to start the workbench instance.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "repository": { + Type: schema.TypeString, + Required: true, + Description: `The path to the container image repository. +For example: gcr.io/{project_id}/{imageName}`, + }, + "tag": { + Type: schema.TypeString, + Optional: true, + Description: `The tag of the container image. If not specified, this defaults to the latest tag.`, + }, + }, + }, + ConflictsWith: []string{"gce_setup.0.vm_image"}, + }, "data_disks": { Type: schema.TypeList, Computed: true, @@ -547,6 +569,7 @@ Format: {project_id}`, }, }, }, + ConflictsWith: []string{"gce_setup.0.container_image"}, }, }, }, @@ -1155,6 +1178,8 @@ func flattenWorkbenchInstanceGceSetup(v interface{}, d *schema.ResourceData, con flattenWorkbenchInstanceGceSetupServiceAccounts(original["serviceAccounts"], d, config) transformed["vm_image"] = flattenWorkbenchInstanceGceSetupVmImage(original["vmImage"], d, config) + transformed["container_image"] = + flattenWorkbenchInstanceGceSetupContainerImage(original["containerImage"], d, config) transformed["boot_disk"] = flattenWorkbenchInstanceGceSetupBootDisk(original["bootDisk"], d, config) transformed["data_disks"] = @@ -1262,6 +1287,29 @@ func flattenWorkbenchInstanceGceSetupVmImage(v interface{}, d *schema.ResourceDa return d.Get("gce_setup.0.vm_image") } +func flattenWorkbenchInstanceGceSetupContainerImage(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["repository"] = + flattenWorkbenchInstanceGceSetupContainerImageRepository(original["repository"], d, config) + transformed["tag"] = + flattenWorkbenchInstanceGceSetupContainerImageTag(original["tag"], d, config) + return []interface{}{transformed} +} +func flattenWorkbenchInstanceGceSetupContainerImageRepository(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenWorkbenchInstanceGceSetupContainerImageTag(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func flattenWorkbenchInstanceGceSetupBootDisk(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { return nil @@ -1562,6 +1610,13 @@ func expandWorkbenchInstanceGceSetup(v interface{}, d tpgresource.TerraformResou transformed["vmImage"] = transformedVmImage } + transformedContainerImage, err := expandWorkbenchInstanceGceSetupContainerImage(original["container_image"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedContainerImage); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["containerImage"] = transformedContainerImage + } + transformedBootDisk, err := expandWorkbenchInstanceGceSetupBootDisk(original["boot_disk"], d, config) if err != nil { return nil, err @@ -1787,6 +1842,40 @@ func expandWorkbenchInstanceGceSetupVmImageFamily(v interface{}, d tpgresource.T return v, nil } +func expandWorkbenchInstanceGceSetupContainerImage(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.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{}) + + transformedRepository, err := expandWorkbenchInstanceGceSetupContainerImageRepository(original["repository"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedRepository); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["repository"] = transformedRepository + } + + transformedTag, err := expandWorkbenchInstanceGceSetupContainerImageTag(original["tag"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedTag); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["tag"] = transformedTag + } + + return transformed, nil +} + +func expandWorkbenchInstanceGceSetupContainerImageRepository(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandWorkbenchInstanceGceSetupContainerImageTag(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + func expandWorkbenchInstanceGceSetupBootDisk(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { l := v.([]interface{}) if len(l) == 0 || l[0] == nil { diff --git a/google/services/workbench/resource_workbench_instance_generated_test.go b/google/services/workbench/resource_workbench_instance_generated_test.go index df5cbacb1a1..86bdb3d7884 100644 --- a/google/services/workbench/resource_workbench_instance_generated_test.go +++ b/google/services/workbench/resource_workbench_instance_generated_test.go @@ -65,6 +65,47 @@ resource "google_workbench_instance" "instance" { `, context) } +func TestAccWorkbenchInstance_workbenchInstanceBasicContainerExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckWorkbenchInstanceDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccWorkbenchInstance_workbenchInstanceBasicContainerExample(context), + }, + { + ResourceName: "google_workbench_instance.instance", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "instance_owners", "location", "instance_id", "labels", "terraform_labels"}, + }, + }, + }) +} + +func testAccWorkbenchInstance_workbenchInstanceBasicContainerExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_workbench_instance" "instance" { + name = "tf-test-workbench-instance%{random_suffix}" + location = "us-west1-a" + + gce_setup { + container_image { + repository = "us-docker.pkg.dev/deeplearning-platform-release/gcr.io/base-cu113.py310" + tag = "latest" + } + } +} +`, context) +} + func TestAccWorkbenchInstance_workbenchInstanceBasicGpuExample(t *testing.T) { t.Parallel() diff --git a/website/docs/r/workbench_instance.html.markdown b/website/docs/r/workbench_instance.html.markdown index 65f4835777f..6817b67a95e 100644 --- a/website/docs/r/workbench_instance.html.markdown +++ b/website/docs/r/workbench_instance.html.markdown @@ -37,6 +37,27 @@ resource "google_workbench_instance" "instance" { location = "us-west1-a" } ``` +
+ + Open in Cloud Shell + +
+## Example Usage - Workbench Instance Basic Container + + +```hcl +resource "google_workbench_instance" "instance" { + name = "workbench-instance" + location = "us-west1-a" + + gce_setup { + container_image { + repository = "us-docker.pkg.dev/deeplearning-platform-release/gcr.io/base-cu113.py310" + tag = "latest" + } + } +} +```
Open in Cloud Shell @@ -262,6 +283,11 @@ The following arguments are supported: a workbench instance with the environment installed directly on the VM. Structure is [documented below](#nested_vm_image). +* `container_image` - + (Optional) + Use a container image to start the workbench instance. + Structure is [documented below](#nested_container_image). + * `boot_disk` - (Optional) The definition of a boot disk. @@ -356,6 +382,17 @@ The following arguments are supported: Optional. Use this VM image family to find the image; the newest image in this family will be used. +The `container_image` block supports: + +* `repository` - + (Required) + The path to the container image repository. + For example: gcr.io/{project_id}/{imageName} + +* `tag` - + (Optional) + The tag of the container image. If not specified, this defaults to the latest tag. + The `boot_disk` block supports: * `disk_size_gb` -