Skip to content

Commit a2e39fd

Browse files
Add support for Empty Dir Volumes and the Container Dependencies to Cloud Run v2 (#7897) (#5613)
* Add support for the depends_on field in the Cloud Run v2 API. * Add emptyDir volume type for the Cloud Run v2 API * Add Cloud Run v2 Service multi-container example * Add Cloud Run v2 Job empty dir volume example * Add default value for empty dir medium in Cloud Run volumes * Mark empty_dir and depends_on as beta fields Signed-off-by: Modular Magician <[email protected]>
1 parent 1c97b1d commit a2e39fd

File tree

7 files changed

+463
-2
lines changed

7 files changed

+463
-2
lines changed

.changelog/7897.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
```release-note:enhancement
2+
cloudrunv2: Added the beta field `template.containers.depends_on` to `google_cloud_run_v2_service`.
3+
```
4+
```release-note:enhancement
5+
cloudrunv2: Added the beta field `template.volumes.empty_dir` to `google_cloud_run_v2_service`.
6+
```
7+
```release-note:enhancement
8+
cloudrunv2: Added the beta field `template.template.volumes.empty_dir` to `google_cloud_run_v2_job`.
9+
```

google-beta/resource_cloud_run_v2_job.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,28 @@ A duration in seconds with up to nine fractional digits, ending with 's'. Exampl
451451
},
452452
},
453453
},
454+
"empty_dir": {
455+
Type: schema.TypeList,
456+
Optional: true,
457+
Description: `Ephemeral storage used as a shared volume.`,
458+
MaxItems: 1,
459+
Elem: &schema.Resource{
460+
Schema: map[string]*schema.Schema{
461+
"medium": {
462+
Type: schema.TypeString,
463+
Optional: true,
464+
ValidateFunc: verify.ValidateEnum([]string{"MEMORY", ""}),
465+
Description: `The different types of medium supported for EmptyDir. Default value: "MEMORY" Possible values: ["MEMORY"]`,
466+
Default: "MEMORY",
467+
},
468+
"size_limit": {
469+
Type: schema.TypeString,
470+
Optional: true,
471+
Description: `Limit on the storage usable by this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. This field's values are of the 'Quantity' k8s type: https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/quantity/. The default is nil which means that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir.`,
472+
},
473+
},
474+
},
475+
},
454476
"secret": {
455477
Type: schema.TypeList,
456478
Optional: true,
@@ -1770,6 +1792,7 @@ func flattenCloudRunV2JobTemplateTemplateVolumes(v interface{}, d *schema.Resour
17701792
"name": flattenCloudRunV2JobTemplateTemplateVolumesName(original["name"], d, config),
17711793
"secret": flattenCloudRunV2JobTemplateTemplateVolumesSecret(original["secret"], d, config),
17721794
"cloud_sql_instance": flattenCloudRunV2JobTemplateTemplateVolumesCloudSqlInstance(original["cloudSqlInstance"], d, config),
1795+
"empty_dir": flattenCloudRunV2JobTemplateTemplateVolumesEmptyDir(original["emptyDir"], d, config),
17731796
})
17741797
}
17751798
return transformed
@@ -1878,6 +1901,29 @@ func flattenCloudRunV2JobTemplateTemplateVolumesCloudSqlInstanceInstances(v inte
18781901
return v
18791902
}
18801903

1904+
func flattenCloudRunV2JobTemplateTemplateVolumesEmptyDir(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1905+
if v == nil {
1906+
return nil
1907+
}
1908+
original := v.(map[string]interface{})
1909+
if len(original) == 0 {
1910+
return nil
1911+
}
1912+
transformed := make(map[string]interface{})
1913+
transformed["medium"] =
1914+
flattenCloudRunV2JobTemplateTemplateVolumesEmptyDirMedium(original["medium"], d, config)
1915+
transformed["size_limit"] =
1916+
flattenCloudRunV2JobTemplateTemplateVolumesEmptyDirSizeLimit(original["sizeLimit"], d, config)
1917+
return []interface{}{transformed}
1918+
}
1919+
func flattenCloudRunV2JobTemplateTemplateVolumesEmptyDirMedium(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1920+
return v
1921+
}
1922+
1923+
func flattenCloudRunV2JobTemplateTemplateVolumesEmptyDirSizeLimit(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1924+
return v
1925+
}
1926+
18811927
func flattenCloudRunV2JobTemplateTemplateTimeout(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
18821928
return v
18831929
}
@@ -2976,6 +3022,13 @@ func expandCloudRunV2JobTemplateTemplateVolumes(v interface{}, d tpgresource.Ter
29763022
transformed["cloudSqlInstance"] = transformedCloudSqlInstance
29773023
}
29783024

3025+
transformedEmptyDir, err := expandCloudRunV2JobTemplateTemplateVolumesEmptyDir(original["empty_dir"], d, config)
3026+
if err != nil {
3027+
return nil, err
3028+
} else if val := reflect.ValueOf(transformedEmptyDir); val.IsValid() && !tpgresource.IsEmptyValue(val) {
3029+
transformed["emptyDir"] = transformedEmptyDir
3030+
}
3031+
29793032
req = append(req, transformed)
29803033
}
29813034
return req, nil
@@ -3097,6 +3150,40 @@ func expandCloudRunV2JobTemplateTemplateVolumesCloudSqlInstanceInstances(v inter
30973150
return v, nil
30983151
}
30993152

3153+
func expandCloudRunV2JobTemplateTemplateVolumesEmptyDir(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
3154+
l := v.([]interface{})
3155+
if len(l) == 0 || l[0] == nil {
3156+
return nil, nil
3157+
}
3158+
raw := l[0]
3159+
original := raw.(map[string]interface{})
3160+
transformed := make(map[string]interface{})
3161+
3162+
transformedMedium, err := expandCloudRunV2JobTemplateTemplateVolumesEmptyDirMedium(original["medium"], d, config)
3163+
if err != nil {
3164+
return nil, err
3165+
} else if val := reflect.ValueOf(transformedMedium); val.IsValid() && !tpgresource.IsEmptyValue(val) {
3166+
transformed["medium"] = transformedMedium
3167+
}
3168+
3169+
transformedSizeLimit, err := expandCloudRunV2JobTemplateTemplateVolumesEmptyDirSizeLimit(original["size_limit"], d, config)
3170+
if err != nil {
3171+
return nil, err
3172+
} else if val := reflect.ValueOf(transformedSizeLimit); val.IsValid() && !tpgresource.IsEmptyValue(val) {
3173+
transformed["sizeLimit"] = transformedSizeLimit
3174+
}
3175+
3176+
return transformed, nil
3177+
}
3178+
3179+
func expandCloudRunV2JobTemplateTemplateVolumesEmptyDirMedium(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
3180+
return v, nil
3181+
}
3182+
3183+
func expandCloudRunV2JobTemplateTemplateVolumesEmptyDirSizeLimit(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
3184+
return v, nil
3185+
}
3186+
31003187
func expandCloudRunV2JobTemplateTemplateTimeout(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
31013188
return v, nil
31023189
}

google-beta/resource_cloud_run_v2_job_generated_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,66 @@ resource "google_secret_manager_secret_iam_member" "secret-access" {
341341
`, context)
342342
}
343343

344+
func TestAccCloudRunV2Job_cloudrunv2JobEmptydirExample(t *testing.T) {
345+
t.Parallel()
346+
347+
context := map[string]interface{}{
348+
"random_suffix": RandString(t, 10),
349+
}
350+
351+
VcrTest(t, resource.TestCase{
352+
PreCheck: func() { acctest.AccTestPreCheck(t) },
353+
ProtoV5ProviderFactories: ProtoV5ProviderBetaFactories(t),
354+
CheckDestroy: testAccCheckCloudRunV2JobDestroyProducer(t),
355+
Steps: []resource.TestStep{
356+
{
357+
Config: testAccCloudRunV2Job_cloudrunv2JobEmptydirExample(context),
358+
},
359+
{
360+
ResourceName: "google_cloud_run_v2_job.default",
361+
ImportState: true,
362+
ImportStateVerify: true,
363+
ImportStateVerifyIgnore: []string{"name", "location"},
364+
},
365+
},
366+
})
367+
}
368+
369+
func testAccCloudRunV2Job_cloudrunv2JobEmptydirExample(context map[string]interface{}) string {
370+
return Nprintf(`
371+
resource "google_cloud_run_v2_job" "default" {
372+
provider = google-beta
373+
name = "tf-test-cloudrun-job%{random_suffix}"
374+
location = "us-central1"
375+
launch_stage = "BETA"
376+
template {
377+
template {
378+
containers {
379+
image = "us-docker.pkg.dev/cloudrun/container/hello"
380+
volume_mounts {
381+
name = "empty-dir-volume"
382+
mount_path = "/mnt"
383+
}
384+
}
385+
volumes {
386+
name = "empty-dir-volume"
387+
empty_dir {
388+
medium = "MEMORY"
389+
size_limit = "128Mi"
390+
}
391+
}
392+
}
393+
}
394+
395+
lifecycle {
396+
ignore_changes = [
397+
launch_stage,
398+
]
399+
}
400+
}
401+
`, context)
402+
}
403+
344404
func testAccCheckCloudRunV2JobDestroyProducer(t *testing.T) func(s *terraform.State) error {
345405
return func(s *terraform.State) error {
346406
for name, rs := range s.RootModule().Resources {

google-beta/resource_cloud_run_v2_service.go

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func ResourceCloudRunV2Service() *schema.Resource {
6868
"containers": {
6969
Type: schema.TypeList,
7070
Optional: true,
71-
Description: `Holds the single container that defines the unit of execution for this task.`,
71+
Description: `Holds the containers that define the unit of execution for this Service.`,
7272
Elem: &schema.Resource{
7373
Schema: map[string]*schema.Schema{
7474
"image": {
@@ -92,6 +92,14 @@ func ResourceCloudRunV2Service() *schema.Resource {
9292
Type: schema.TypeString,
9393
},
9494
},
95+
"depends_on": {
96+
Type: schema.TypeList,
97+
Optional: true,
98+
Description: `Containers which should be started before this container. If specified the container will wait to start until all containers with the listed names are healthy.`,
99+
Elem: &schema.Schema{
100+
Type: schema.TypeString,
101+
},
102+
},
95103
"env": {
96104
Type: schema.TypeList,
97105
Optional: true,
@@ -558,6 +566,28 @@ A duration in seconds with up to nine fractional digits, ending with 's'. Exampl
558566
},
559567
},
560568
},
569+
"empty_dir": {
570+
Type: schema.TypeList,
571+
Optional: true,
572+
Description: `Ephemeral storage used as a shared volume.`,
573+
MaxItems: 1,
574+
Elem: &schema.Resource{
575+
Schema: map[string]*schema.Schema{
576+
"medium": {
577+
Type: schema.TypeString,
578+
Optional: true,
579+
ValidateFunc: verify.ValidateEnum([]string{"MEMORY", ""}),
580+
Description: `The different types of medium supported for EmptyDir. Default value: "MEMORY" Possible values: ["MEMORY"]`,
581+
Default: "MEMORY",
582+
},
583+
"size_limit": {
584+
Type: schema.TypeString,
585+
Optional: true,
586+
Description: `Limit on the storage usable by this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. This field's values are of the 'Quantity' k8s type: https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/quantity/. The default is nil which means that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir.`,
587+
},
588+
},
589+
},
590+
},
561591
"secret": {
562592
Type: schema.TypeList,
563593
Optional: true,
@@ -1533,6 +1563,7 @@ func flattenCloudRunV2ServiceTemplateContainers(v interface{}, d *schema.Resourc
15331563
"working_dir": flattenCloudRunV2ServiceTemplateContainersWorkingDir(original["workingDir"], d, config),
15341564
"liveness_probe": flattenCloudRunV2ServiceTemplateContainersLivenessProbe(original["livenessProbe"], d, config),
15351565
"startup_probe": flattenCloudRunV2ServiceTemplateContainersStartupProbe(original["startupProbe"], d, config),
1566+
"depends_on": flattenCloudRunV2ServiceTemplateContainersDependsOn(original["dependsOn"], d, config),
15361567
})
15371568
}
15381569
return transformed
@@ -2147,6 +2178,10 @@ func flattenCloudRunV2ServiceTemplateContainersStartupProbeGrpcService(v interfa
21472178
return v
21482179
}
21492180

2181+
func flattenCloudRunV2ServiceTemplateContainersDependsOn(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
2182+
return v
2183+
}
2184+
21502185
func flattenCloudRunV2ServiceTemplateVolumes(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
21512186
if v == nil {
21522187
return v
@@ -2163,6 +2198,7 @@ func flattenCloudRunV2ServiceTemplateVolumes(v interface{}, d *schema.ResourceDa
21632198
"name": flattenCloudRunV2ServiceTemplateVolumesName(original["name"], d, config),
21642199
"secret": flattenCloudRunV2ServiceTemplateVolumesSecret(original["secret"], d, config),
21652200
"cloud_sql_instance": flattenCloudRunV2ServiceTemplateVolumesCloudSqlInstance(original["cloudSqlInstance"], d, config),
2201+
"empty_dir": flattenCloudRunV2ServiceTemplateVolumesEmptyDir(original["emptyDir"], d, config),
21662202
})
21672203
}
21682204
return transformed
@@ -2271,6 +2307,29 @@ func flattenCloudRunV2ServiceTemplateVolumesCloudSqlInstanceInstances(v interfac
22712307
return v
22722308
}
22732309

2310+
func flattenCloudRunV2ServiceTemplateVolumesEmptyDir(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
2311+
if v == nil {
2312+
return nil
2313+
}
2314+
original := v.(map[string]interface{})
2315+
if len(original) == 0 {
2316+
return nil
2317+
}
2318+
transformed := make(map[string]interface{})
2319+
transformed["medium"] =
2320+
flattenCloudRunV2ServiceTemplateVolumesEmptyDirMedium(original["medium"], d, config)
2321+
transformed["size_limit"] =
2322+
flattenCloudRunV2ServiceTemplateVolumesEmptyDirSizeLimit(original["sizeLimit"], d, config)
2323+
return []interface{}{transformed}
2324+
}
2325+
func flattenCloudRunV2ServiceTemplateVolumesEmptyDirMedium(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
2326+
return v
2327+
}
2328+
2329+
func flattenCloudRunV2ServiceTemplateVolumesEmptyDirSizeLimit(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
2330+
return v
2331+
}
2332+
22742333
func flattenCloudRunV2ServiceTemplateExecutionEnvironment(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
22752334
return v
22762335
}
@@ -2913,6 +2972,13 @@ func expandCloudRunV2ServiceTemplateContainers(v interface{}, d tpgresource.Terr
29132972
transformed["startupProbe"] = transformedStartupProbe
29142973
}
29152974

2975+
transformedDependsOn, err := expandCloudRunV2ServiceTemplateContainersDependsOn(original["depends_on"], d, config)
2976+
if err != nil {
2977+
return nil, err
2978+
} else if val := reflect.ValueOf(transformedDependsOn); val.IsValid() && !tpgresource.IsEmptyValue(val) {
2979+
transformed["dependsOn"] = transformedDependsOn
2980+
}
2981+
29162982
req = append(req, transformed)
29172983
}
29182984
return req, nil
@@ -3615,6 +3681,10 @@ func expandCloudRunV2ServiceTemplateContainersStartupProbeGrpcService(v interfac
36153681
return v, nil
36163682
}
36173683

3684+
func expandCloudRunV2ServiceTemplateContainersDependsOn(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
3685+
return v, nil
3686+
}
3687+
36183688
func expandCloudRunV2ServiceTemplateVolumes(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
36193689
l := v.([]interface{})
36203690
req := make([]interface{}, 0, len(l))
@@ -3646,6 +3716,13 @@ func expandCloudRunV2ServiceTemplateVolumes(v interface{}, d tpgresource.Terrafo
36463716
transformed["cloudSqlInstance"] = transformedCloudSqlInstance
36473717
}
36483718

3719+
transformedEmptyDir, err := expandCloudRunV2ServiceTemplateVolumesEmptyDir(original["empty_dir"], d, config)
3720+
if err != nil {
3721+
return nil, err
3722+
} else if val := reflect.ValueOf(transformedEmptyDir); val.IsValid() && !tpgresource.IsEmptyValue(val) {
3723+
transformed["emptyDir"] = transformedEmptyDir
3724+
}
3725+
36493726
req = append(req, transformed)
36503727
}
36513728
return req, nil
@@ -3767,6 +3844,40 @@ func expandCloudRunV2ServiceTemplateVolumesCloudSqlInstanceInstances(v interface
37673844
return v, nil
37683845
}
37693846

3847+
func expandCloudRunV2ServiceTemplateVolumesEmptyDir(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
3848+
l := v.([]interface{})
3849+
if len(l) == 0 || l[0] == nil {
3850+
return nil, nil
3851+
}
3852+
raw := l[0]
3853+
original := raw.(map[string]interface{})
3854+
transformed := make(map[string]interface{})
3855+
3856+
transformedMedium, err := expandCloudRunV2ServiceTemplateVolumesEmptyDirMedium(original["medium"], d, config)
3857+
if err != nil {
3858+
return nil, err
3859+
} else if val := reflect.ValueOf(transformedMedium); val.IsValid() && !tpgresource.IsEmptyValue(val) {
3860+
transformed["medium"] = transformedMedium
3861+
}
3862+
3863+
transformedSizeLimit, err := expandCloudRunV2ServiceTemplateVolumesEmptyDirSizeLimit(original["size_limit"], d, config)
3864+
if err != nil {
3865+
return nil, err
3866+
} else if val := reflect.ValueOf(transformedSizeLimit); val.IsValid() && !tpgresource.IsEmptyValue(val) {
3867+
transformed["sizeLimit"] = transformedSizeLimit
3868+
}
3869+
3870+
return transformed, nil
3871+
}
3872+
3873+
func expandCloudRunV2ServiceTemplateVolumesEmptyDirMedium(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
3874+
return v, nil
3875+
}
3876+
3877+
func expandCloudRunV2ServiceTemplateVolumesEmptyDirSizeLimit(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
3878+
return v, nil
3879+
}
3880+
37703881
func expandCloudRunV2ServiceTemplateExecutionEnvironment(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
37713882
return v, nil
37723883
}

0 commit comments

Comments
 (0)