From a92d548e1661f6625256c6be5a8b88f8c791d4b1 Mon Sep 17 00:00:00 2001 From: Mark van Holsteijn Date: Thu, 11 Jan 2024 15:30:23 +0100 Subject: [PATCH] Add support for NFS and GCS mounts in Cloud Run v2 service (#9728) * feat: add support for NFS and GCS mounts in Cloud Run v2 service ```release-note:enhancement cloudrunv2: added `nfs` field to `google_cloud_run_v2_service.template.volumes` cloudrunv2: added `gcs` field to `google_cloud_run_v2_service.template.volumes` cloudrunv2: adding tcpSocket field to `google_cloud_run_v2.template.containers.livenessProbe` ``` * fix: add required to relevant properties --- mmv1/products/cloudrunv2/Service.yaml | 92 +++++++++++++------ .../cloudrunv2_service_mount_gcs.tf.erb | 31 +++++++ .../cloudrunv2_service_mount_nfs.tf.erb | 49 ++++++++++ 3 files changed, 144 insertions(+), 28 deletions(-) create mode 100644 mmv1/templates/terraform/examples/cloudrunv2_service_mount_gcs.tf.erb create mode 100644 mmv1/templates/terraform/examples/cloudrunv2_service_mount_nfs.tf.erb diff --git a/mmv1/products/cloudrunv2/Service.yaml b/mmv1/products/cloudrunv2/Service.yaml index 07bdcba208f4..1d4c3b7a0895 100644 --- a/mmv1/products/cloudrunv2/Service.yaml +++ b/mmv1/products/cloudrunv2/Service.yaml @@ -27,11 +27,7 @@ iam_policy: !ruby/object:Api::Resource::IamPolicy method_name_separator: ':' parent_resource_attribute: 'name' base_url: projects/{{project}}/locations/{{location}}/services/{{name}} - import_format: - [ - 'projects/{{project}}/locations/{{location}}/services/{{name}}', - '{{name}}', - ] + import_format: ['projects/{{project}}/locations/{{location}}/services/{{name}}', '{{name}}'] async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' @@ -56,9 +52,7 @@ examples: - !ruby/object:Provider::Terraform::Examples name: 'cloudrunv2_service_basic' primary_resource_id: 'default' - primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-service%s\", - context[\"\ - random_suffix\"])" + primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-service%s\", context[\"random_suffix\"])" vars: cloud_run_service_name: 'cloudrun-service' - !ruby/object:Provider::Terraform::Examples @@ -69,9 +63,7 @@ examples: - !ruby/object:Provider::Terraform::Examples name: 'cloudrunv2_service_sql' primary_resource_id: 'default' - primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-srv%s\", - context[\"random_suffix\"\ - ])" + primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-srv%s\", context[\"random_suffix\"])" vars: cloud_run_service_name: 'cloudrun-service' secret_id: 'secret-1' @@ -84,9 +76,7 @@ examples: - !ruby/object:Provider::Terraform::Examples name: 'cloudrunv2_service_vpcaccess' primary_resource_id: 'default' - primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-srv%s\", - context[\"random_suffix\"\ - ])" + primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-srv%s\", context[\"random_suffix\"])" vars: cloud_run_service_name: 'cloudrun-service' vpc_access_connector_name: 'run-vpc' @@ -95,25 +85,19 @@ examples: - !ruby/object:Provider::Terraform::Examples name: 'cloudrunv2_service_directvpc' primary_resource_id: 'default' - primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-srv%s\", - context[\"random_suffix\"\ - ])" + primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-srv%s\", context[\"random_suffix\"])" vars: cloud_run_service_name: 'cloudrun-service' - !ruby/object:Provider::Terraform::Examples name: 'cloudrunv2_service_probes' primary_resource_id: 'default' - primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-srv%s\", - context[\"random_suffix\"\ - ])" + primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-srv%s\", context[\"random_suffix\"])" vars: cloud_run_service_name: 'cloudrun-service' - !ruby/object:Provider::Terraform::Examples name: 'cloudrunv2_service_secret' primary_resource_id: 'default' - primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-srv%s\", - context[\"random_suffix\"\ - ])" + primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-srv%s\", context[\"random_suffix\"])" vars: cloud_run_service_name: 'cloudrun-service' secret_id: 'secret-1' @@ -125,6 +109,21 @@ examples: random_suffix\"])" vars: cloud_run_service_name: 'cloudrun-service' + + - !ruby/object:Provider::Terraform::Examples + name: 'cloudrunv2_service_mount_gcs' + primary_resource_id: 'default' + primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-service-%s\", context[\"random_suffix\"])" + vars: + cloud_run_service_name: 'cloudrun-service' + + - !ruby/object:Provider::Terraform::Examples + name: 'cloudrunv2_service_mount_nfs' + primary_resource_id: 'default' + primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-service-%s\", context[\"random_suffix\"])" + vars: + cloud_run_service_name: 'cloudrun-service' + parameters: - !ruby/object:Api::Type::String name: 'location' @@ -554,6 +553,17 @@ properties: The name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). If this is not specified, the default behavior is defined by gRPC. + - !ruby/object:Api::Type::NestedObject + name: tcpSocket + description: TCPSocketAction describes an action based on opening a socket + properties: + - !ruby/object:Api::Type::Integer + name: port + description: |- + Port number to access on the container. Must be in the range 1 to 65535. + If not specified, defaults to the exposed port of the container, which + is the value of container.ports[0].containerPort. + required: true - !ruby/object:Api::Type::NestedObject name: 'startupProbe' description: |- @@ -585,8 +595,7 @@ properties: description: |- HTTPGet specifies the http request to perform. Exactly one of HTTPGet or TCPSocket must be specified. send_empty_value: true - allow_empty_object: - true + allow_empty_object: true # exactly_one_of: # - template.0.containers.0.startupProbe.0.httpGet # - template.0.containers.0.startupProbe.0.tcpSocket @@ -625,8 +634,7 @@ properties: description: |- TCPSocket specifies an action involving a TCP port. Exactly one of HTTPGet or TCPSocket must be specified. send_empty_value: true - allow_empty_object: - true + allow_empty_object: true # exactly_one_of: # - template.0.containers.0.startupProbe.0.httpGet # - template.0.containers.0.startupProbe.0.tcpSocket @@ -749,7 +757,35 @@ properties: - !ruby/object:Api::Type::String name: 'sizeLimit' 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: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir. + 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: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir. + - !ruby/object:Api::Type::NestedObject + name: gcs + description: Represents a GCS Bucket mounted as a volume. + properties: + - !ruby/object:Api::Type::String + name: bucket + description: GCS Bucket name + required: true + - !ruby/object:Api::Type::Boolean + name: readOnly + description: If true, mount the GCS bucket as read-only + required: false + - !ruby/object:Api::Type::NestedObject + name: nfs + description: Represents an NFS mount. + properties: + - !ruby/object:Api::Type::String + name: server + description: Hostname or IP address of the NFS server + required: true + - !ruby/object:Api::Type::String + name: path + description: Path that is exported by the NFS server. + required: true + - !ruby/object:Api::Type::Boolean + name: readOnly + description: If true, mount the NFS volume as read only + required: false - !ruby/object:Api::Type::Enum name: 'executionEnvironment' description: |- diff --git a/mmv1/templates/terraform/examples/cloudrunv2_service_mount_gcs.tf.erb b/mmv1/templates/terraform/examples/cloudrunv2_service_mount_gcs.tf.erb new file mode 100644 index 000000000000..802110524ba3 --- /dev/null +++ b/mmv1/templates/terraform/examples/cloudrunv2_service_mount_gcs.tf.erb @@ -0,0 +1,31 @@ +resource "google_cloud_run_v2_service" "<%= ctx[:primary_resource_id] %>" { + name = "<%= ctx[:vars]['cloud_run_service_name'] %>" + + location = "us-central1" + launch_stage = "BETA" + + template { + execution_environment = "EXECUTION_ENVIRONMENT_GEN2" + + containers { + image = "us-docker.pkg.dev/cloudrun/container/hello" + volume_mounts { + name = "bucket" + mount_path = "/var/www" + } + } + + volumes { + name = "bucket" + gcs { + bucket = google_storage_bucket.<%= ctx[:primary_resource_id] %>.name + read_only = false + } + } + } +} + +resource "google_storage_bucket" "<%= ctx[:primary_resource_id] %>" { + name = "<%= ctx[:vars]['cloud_run_service_name'] %>" + location = "US" +} diff --git a/mmv1/templates/terraform/examples/cloudrunv2_service_mount_nfs.tf.erb b/mmv1/templates/terraform/examples/cloudrunv2_service_mount_nfs.tf.erb new file mode 100644 index 000000000000..9f3451907065 --- /dev/null +++ b/mmv1/templates/terraform/examples/cloudrunv2_service_mount_nfs.tf.erb @@ -0,0 +1,49 @@ +resource "google_cloud_run_v2_service" "<%= ctx[:primary_resource_id] %>" { + name = "<%= ctx[:vars]['cloud_run_service_name'] %>" + + location = "us-central1" + ingress = "INGRESS_TRAFFIC_ALL" + launch_stage = "BETA" + + template { + execution_environment = "EXECUTION_ENVIRONMENT_GEN2" + containers { + image = "us-docker.pkg.dev/cloudrun/container/hello:latest" + volume_mounts { + name = "nfs" + mount_path = "/mnt/nfs/filestore" + } + } + vpc_access { + network_interfaces { + network = "default" + subnetwork = "default" + } + } + + volumes { + name = "nfs" + nfs { + server = google_filestore_instance.default.networks[0].ip_addresses[0] + path = "/share1" + read_only = false + } + } + } +} + +resource "google_filestore_instance" "<%= ctx[:primary_resource_id] %>" { + name = "<%= ctx[:vars]['cloud_run_service_name'] %>" + location = "us-central1-b" + tier = "BASIC_HDD" + + file_shares { + capacity_gb = 1024 + name = "share1" + } + + networks { + network = "default" + modes = ["MODE_IPV4"] + } +} \ No newline at end of file