Skip to content

Commit 03954f7

Browse files
Add support for custom containers for workbench instances (#9973) (#6988)
* Add support for custom containers for workbench instances * Use conflicts instead of exactly_one_of for backward compatibility [upstream:aeba6c4947923df75d25ce0ec3e710b6d0140b48] Signed-off-by: Modular Magician <[email protected]>
1 parent d693684 commit 03954f7

File tree

4 files changed

+170
-0
lines changed

4 files changed

+170
-0
lines changed

.changelog/9973.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
workbench: added `container_image` field to `google_workbench_instance` resource
3+
```

google-beta/services/workbench/resource_workbench_instance.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,28 @@ Learn more about using your own encryption keys.'`,
328328
},
329329
},
330330
},
331+
"container_image": {
332+
Type: schema.TypeList,
333+
Optional: true,
334+
Description: `Use a container image to start the workbench instance.`,
335+
MaxItems: 1,
336+
Elem: &schema.Resource{
337+
Schema: map[string]*schema.Schema{
338+
"repository": {
339+
Type: schema.TypeString,
340+
Required: true,
341+
Description: `The path to the container image repository.
342+
For example: gcr.io/{project_id}/{imageName}`,
343+
},
344+
"tag": {
345+
Type: schema.TypeString,
346+
Optional: true,
347+
Description: `The tag of the container image. If not specified, this defaults to the latest tag.`,
348+
},
349+
},
350+
},
351+
ConflictsWith: []string{"gce_setup.0.vm_image"},
352+
},
331353
"data_disks": {
332354
Type: schema.TypeList,
333355
Computed: true,
@@ -547,6 +569,7 @@ Format: {project_id}`,
547569
},
548570
},
549571
},
572+
ConflictsWith: []string{"gce_setup.0.container_image"},
550573
},
551574
},
552575
},
@@ -1155,6 +1178,8 @@ func flattenWorkbenchInstanceGceSetup(v interface{}, d *schema.ResourceData, con
11551178
flattenWorkbenchInstanceGceSetupServiceAccounts(original["serviceAccounts"], d, config)
11561179
transformed["vm_image"] =
11571180
flattenWorkbenchInstanceGceSetupVmImage(original["vmImage"], d, config)
1181+
transformed["container_image"] =
1182+
flattenWorkbenchInstanceGceSetupContainerImage(original["containerImage"], d, config)
11581183
transformed["boot_disk"] =
11591184
flattenWorkbenchInstanceGceSetupBootDisk(original["bootDisk"], d, config)
11601185
transformed["data_disks"] =
@@ -1262,6 +1287,29 @@ func flattenWorkbenchInstanceGceSetupVmImage(v interface{}, d *schema.ResourceDa
12621287
return d.Get("gce_setup.0.vm_image")
12631288
}
12641289

1290+
func flattenWorkbenchInstanceGceSetupContainerImage(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1291+
if v == nil {
1292+
return nil
1293+
}
1294+
original := v.(map[string]interface{})
1295+
if len(original) == 0 {
1296+
return nil
1297+
}
1298+
transformed := make(map[string]interface{})
1299+
transformed["repository"] =
1300+
flattenWorkbenchInstanceGceSetupContainerImageRepository(original["repository"], d, config)
1301+
transformed["tag"] =
1302+
flattenWorkbenchInstanceGceSetupContainerImageTag(original["tag"], d, config)
1303+
return []interface{}{transformed}
1304+
}
1305+
func flattenWorkbenchInstanceGceSetupContainerImageRepository(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1306+
return v
1307+
}
1308+
1309+
func flattenWorkbenchInstanceGceSetupContainerImageTag(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1310+
return v
1311+
}
1312+
12651313
func flattenWorkbenchInstanceGceSetupBootDisk(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
12661314
if v == nil {
12671315
return nil
@@ -1562,6 +1610,13 @@ func expandWorkbenchInstanceGceSetup(v interface{}, d tpgresource.TerraformResou
15621610
transformed["vmImage"] = transformedVmImage
15631611
}
15641612

1613+
transformedContainerImage, err := expandWorkbenchInstanceGceSetupContainerImage(original["container_image"], d, config)
1614+
if err != nil {
1615+
return nil, err
1616+
} else if val := reflect.ValueOf(transformedContainerImage); val.IsValid() && !tpgresource.IsEmptyValue(val) {
1617+
transformed["containerImage"] = transformedContainerImage
1618+
}
1619+
15651620
transformedBootDisk, err := expandWorkbenchInstanceGceSetupBootDisk(original["boot_disk"], d, config)
15661621
if err != nil {
15671622
return nil, err
@@ -1787,6 +1842,40 @@ func expandWorkbenchInstanceGceSetupVmImageFamily(v interface{}, d tpgresource.T
17871842
return v, nil
17881843
}
17891844

1845+
func expandWorkbenchInstanceGceSetupContainerImage(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1846+
l := v.([]interface{})
1847+
if len(l) == 0 || l[0] == nil {
1848+
return nil, nil
1849+
}
1850+
raw := l[0]
1851+
original := raw.(map[string]interface{})
1852+
transformed := make(map[string]interface{})
1853+
1854+
transformedRepository, err := expandWorkbenchInstanceGceSetupContainerImageRepository(original["repository"], d, config)
1855+
if err != nil {
1856+
return nil, err
1857+
} else if val := reflect.ValueOf(transformedRepository); val.IsValid() && !tpgresource.IsEmptyValue(val) {
1858+
transformed["repository"] = transformedRepository
1859+
}
1860+
1861+
transformedTag, err := expandWorkbenchInstanceGceSetupContainerImageTag(original["tag"], d, config)
1862+
if err != nil {
1863+
return nil, err
1864+
} else if val := reflect.ValueOf(transformedTag); val.IsValid() && !tpgresource.IsEmptyValue(val) {
1865+
transformed["tag"] = transformedTag
1866+
}
1867+
1868+
return transformed, nil
1869+
}
1870+
1871+
func expandWorkbenchInstanceGceSetupContainerImageRepository(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1872+
return v, nil
1873+
}
1874+
1875+
func expandWorkbenchInstanceGceSetupContainerImageTag(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1876+
return v, nil
1877+
}
1878+
17901879
func expandWorkbenchInstanceGceSetupBootDisk(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
17911880
l := v.([]interface{})
17921881
if len(l) == 0 || l[0] == nil {

google-beta/services/workbench/resource_workbench_instance_generated_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,47 @@ resource "google_workbench_instance" "instance" {
6565
`, context)
6666
}
6767

68+
func TestAccWorkbenchInstance_workbenchInstanceBasicContainerExample(t *testing.T) {
69+
t.Parallel()
70+
71+
context := map[string]interface{}{
72+
"random_suffix": acctest.RandString(t, 10),
73+
}
74+
75+
acctest.VcrTest(t, resource.TestCase{
76+
PreCheck: func() { acctest.AccTestPreCheck(t) },
77+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
78+
CheckDestroy: testAccCheckWorkbenchInstanceDestroyProducer(t),
79+
Steps: []resource.TestStep{
80+
{
81+
Config: testAccWorkbenchInstance_workbenchInstanceBasicContainerExample(context),
82+
},
83+
{
84+
ResourceName: "google_workbench_instance.instance",
85+
ImportState: true,
86+
ImportStateVerify: true,
87+
ImportStateVerifyIgnore: []string{"name", "instance_owners", "location", "instance_id", "labels", "terraform_labels"},
88+
},
89+
},
90+
})
91+
}
92+
93+
func testAccWorkbenchInstance_workbenchInstanceBasicContainerExample(context map[string]interface{}) string {
94+
return acctest.Nprintf(`
95+
resource "google_workbench_instance" "instance" {
96+
name = "tf-test-workbench-instance%{random_suffix}"
97+
location = "us-west1-a"
98+
99+
gce_setup {
100+
container_image {
101+
repository = "us-docker.pkg.dev/deeplearning-platform-release/gcr.io/base-cu113.py310"
102+
tag = "latest"
103+
}
104+
}
105+
}
106+
`, context)
107+
}
108+
68109
func TestAccWorkbenchInstance_workbenchInstanceBasicGpuExample(t *testing.T) {
69110
t.Parallel()
70111

website/docs/r/workbench_instance.html.markdown

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,27 @@ resource "google_workbench_instance" "instance" {
3737
location = "us-west1-a"
3838
}
3939
```
40+
<div class = "oics-button" style="float: right; margin: 0 0 -15px">
41+
<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=workbench_instance_basic_container&cloudshell_image=gcr.io%2Fcloudshell-images%2Fcloudshell%3Alatest&open_in_editor=main.tf&cloudshell_print=.%2Fmotd&cloudshell_tutorial=.%2Ftutorial.md" target="_blank">
42+
<img alt="Open in Cloud Shell" src="//gstatic.com/cloudssh/images/open-btn.svg" style="max-height: 44px; margin: 32px auto; max-width: 100%;">
43+
</a>
44+
</div>
45+
## Example Usage - Workbench Instance Basic Container
46+
47+
48+
```hcl
49+
resource "google_workbench_instance" "instance" {
50+
name = "workbench-instance"
51+
location = "us-west1-a"
52+
53+
gce_setup {
54+
container_image {
55+
repository = "us-docker.pkg.dev/deeplearning-platform-release/gcr.io/base-cu113.py310"
56+
tag = "latest"
57+
}
58+
}
59+
}
60+
```
4061
<div class = "oics-button" style="float: right; margin: 0 0 -15px">
4162
<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=workbench_instance_basic_gpu&cloudshell_image=gcr.io%2Fcloudshell-images%2Fcloudshell%3Alatest&open_in_editor=main.tf&cloudshell_print=.%2Fmotd&cloudshell_tutorial=.%2Ftutorial.md" target="_blank">
4263
<img alt="Open in Cloud Shell" src="//gstatic.com/cloudssh/images/open-btn.svg" style="max-height: 44px; margin: 32px auto; max-width: 100%;">
@@ -262,6 +283,11 @@ The following arguments are supported:
262283
a workbench instance with the environment installed directly on the VM.
263284
Structure is [documented below](#nested_vm_image).
264285

286+
* `container_image` -
287+
(Optional)
288+
Use a container image to start the workbench instance.
289+
Structure is [documented below](#nested_container_image).
290+
265291
* `boot_disk` -
266292
(Optional)
267293
The definition of a boot disk.
@@ -356,6 +382,17 @@ The following arguments are supported:
356382
Optional. Use this VM image family to find the image; the newest
357383
image in this family will be used.
358384

385+
<a name="nested_container_image"></a>The `container_image` block supports:
386+
387+
* `repository` -
388+
(Required)
389+
The path to the container image repository.
390+
For example: gcr.io/{project_id}/{imageName}
391+
392+
* `tag` -
393+
(Optional)
394+
The tag of the container image. If not specified, this defaults to the latest tag.
395+
359396
<a name="nested_boot_disk"></a>The `boot_disk` block supports:
360397

361398
* `disk_size_gb` -

0 commit comments

Comments
 (0)