FAQ | This is a LIVE service | Changelog

Skip to content
Snippets Groups Projects
Commit 642dd069 authored by Kevin Hooke's avatar Kevin Hooke Committed by Dr Rich Wareham
Browse files

feat: added gcs volume type

parent 32060e4d
No related branches found
No related tags found
1 merge request!88Added support for provisioning gcs volume types
Pipeline #719951 passed
......@@ -125,7 +125,7 @@ For more information on how the pre-deploy Cloud Run job works see the
| <a name="input_template_labels"></a> [template\_labels](#input\_template\_labels) | A set of key/value label pairs to assign to the Cloud Run service revision. | `map(string)` | `{}` | no |
| <a name="input_timeout_seconds"></a> [timeout\_seconds](#input\_timeout\_seconds) | The maximum duration, in seconds, the instance is allowed for responding to a<br>request. Maximum is 900s. | `string` | `"300s"` | no |
| <a name="input_traffic"></a> [traffic](#input\_traffic) | Configure traffic allocation between one or more service revisions. | <pre>list(object({<br> type = optional(string)<br> revision = optional(string)<br> percent = optional(number)<br> tag = optional(string)<br> }))</pre> | `[]` | no |
| <a name="input_volumes"></a> [volumes](#input\_volumes) | Configure one or more volumes for the service. See<br>https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloud_run_v2_service#nested_volumes<br>for more information on these options. | <pre>list(object({<br> name = string<br> secret = optional(object({<br> secret = string<br> default_mode = optional(number)<br> items = optional(list(object({<br> path = string<br> version = optional(string)<br> mode = optional(number)<br> })), [])<br> }))<br> cloud_sql_instance = optional(object({<br> instances = optional(list(string))<br> }))<br> }))</pre> | `[]` | no |
| <a name="input_volumes"></a> [volumes](#input\_volumes) | Configure one or more volumes for the service. See<br>https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloud_run_v2_service#nested_volumes<br>for more information on these options. | <pre>list(object({<br> name = string<br> secret = optional(object({<br> secret = string<br> default_mode = optional(number)<br> items = optional(list(object({<br> path = string<br> version = optional(string)<br> mode = optional(number)<br> })), [])<br> }))<br> gcs = optional(object({<br> bucket = string<br> read_only = optional(bool)<br> }))<br> cloud_sql_instance = optional(object({<br> instances = optional(list(string))<br> }))<br> }))</pre> | `[]` | no |
| <a name="input_vpc_access"></a> [vpc\_access](#input\_vpc\_access) | Configure VPC access for the Cloud Run service. For more information on these<br>options see<br>https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloud_run_v2_service#nested_vpc_access | <pre>object({<br> connector = optional(string)<br> egress = optional(string)<br> network_interfaces = optional(object({<br> network = optional(string)<br> subnetwork = optional(string)<br> tags = optional(string)<br> }))<br> })</pre> | `null` | no |
| <a name="input_vpc_access_connector_max_throughput"></a> [vpc\_access\_connector\_max\_throughput](#input\_vpc\_access\_connector\_max\_throughput) | Optional. The maximum throughput of the connector in megabytes per second.<br>Defaults to 300. | `number` | `300` | no |
| <a name="input_vpc_access_connector_min_throughput"></a> [vpc\_access\_connector\_min\_throughput](#input\_vpc\_access\_connector\_min\_throughput) | Optional. The minimum throughput of the connector in megabytes per second.<br>Defaults to 200. | `number` | `200` | no |
......
......@@ -223,6 +223,13 @@ resource "google_cloud_run_v2_service" "webapp" {
instances = cloud_sql_instance.value["instances"]
}
}
dynamic "gcs" {
for_each = volume.value["gcs"] != null ? [volume.value["gcs"]] : []
content {
bucket = gcs.value["bucket"]
read_only = gcs.value["read_only"] != null ? gcs.value["read_only"] : true
}
}
}
}
dynamic "volumes" {
......
......@@ -67,6 +67,15 @@ for bucket in "${buckets[@]}"; do
gcloud --project="$GCP_PROJECT" storage rm -r "$bucket" --quiet
done
mapfile -t bucketsgcs < <(
gcloud --project="$GCP_PROJECT" storage buckets list \
--filter="name ~ ${TEST_PREFIX::8}-gcs" --format="value(storage_url)"
)
for bucket in "${bucketsgcs[@]}"; do
gcloud --project="$GCP_PROJECT" storage rm -r "$bucket" --quiet
done
echo "Cleaning up Cloud Monitoring resources..."
mapfile -t alert_policies < <(
gcloud alpha --project="$GCP_PROJECT" monitoring policies list \
......
......@@ -231,6 +231,57 @@ run "test_env_vars_and_secrets" {
}
}
run "setup_gcs_bucket" {
variables {
create_gcs_bucket = true
}
module {
source = "./tests/setup"
}
}
run "test_gcs_volume" {
variables {
name = run.setup_gcs_bucket.random_name
execution_environment = "EXECUTION_ENVIRONMENT_GEN2"
containers = {
webapp = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
volume_mounts = [
{
name = "test-gcs-volume",
mount_path = "/gcs"
}
]
}
}
volumes = [
{
name = "test-gcs-volume"
gcs = {
bucket = run.setup_gcs_bucket.gcs_bucket_name
read_only = true
}
}
]
deletion_protection = false
}
assert {
condition = google_cloud_run_v2_service.webapp.template[0].containers[0].volume_mounts[0].name == "test-gcs-volume"
error_message = "A volume mount with the name 'test-gcs-volume' should be created."
}
assert {
condition = google_cloud_run_v2_service.webapp.template[0].containers[0].volume_mounts[0].mount_path == "/gcs"
error_message = "A volume mount with the mount path '/gcs' should be created."
}
assert {
condition = google_cloud_run_v2_service.webapp.template[0].volumes[0].name == "test-gcs-volume"
error_message = "A volume with the name 'test-gcs-volume' should be created."
}
}
run "test_service_with_multiple_containers" {
variables {
name = run.setup.random_name
......
......@@ -176,22 +176,22 @@ run "test_service_with_load_balancer_enabled_and_load_balancer_alerting_defaults
}
assert {
condition = google_monitoring_alert_policy.load_balancer_server_error_alerts[0] != null
condition = google_monitoring_alert_policy.load_balancer_server_error_alerts[0] != null
error_message = "An alert policy resource should be created."
}
assert {
condition = google_monitoring_alert_policy.load_balancer_server_error_alerts[0].enabled == true
condition = google_monitoring_alert_policy.load_balancer_server_error_alerts[0].enabled == true
error_message = "Load balancer alert policy should be enabled."
}
assert {
condition = google_monitoring_alert_policy.load_balancer_server_error_alerts[0].conditions[0].condition_threshold[0].threshold_value == 10
condition = google_monitoring_alert_policy.load_balancer_server_error_alerts[0].conditions[0].condition_threshold[0].threshold_value == 10
error_message = "Load balancer alert condition triggers after 10 5XX responses."
}
assert {
condition = google_monitoring_alert_policy.load_balancer_server_error_alerts[0].conditions[0].condition_threshold[0].aggregations[0].alignment_period == "60s"
condition = google_monitoring_alert_policy.load_balancer_server_error_alerts[0].conditions[0].condition_threshold[0].aggregations[0].alignment_period == "60s"
error_message = "Load balancer alert condition aggregates over 60s."
}
}
......@@ -210,24 +210,24 @@ run "test_service_with_load_balancer_enabled_and_load_balancer_alerting" {
}
deletion_protection = false
alerting_load_balancer_server_errors = {
enabled = true
enabled = true
alignment_period = "120s"
threshold = 100
threshold = 100
}
}
assert {
condition = google_monitoring_alert_policy.load_balancer_server_error_alerts[0] != null
condition = google_monitoring_alert_policy.load_balancer_server_error_alerts[0] != null
error_message = "An alert policy resource should be created."
}
assert {
condition = google_monitoring_alert_policy.load_balancer_server_error_alerts[0].conditions[0].condition_threshold[0].threshold_value == 100
condition = google_monitoring_alert_policy.load_balancer_server_error_alerts[0].conditions[0].condition_threshold[0].threshold_value == 100
error_message = "Load balancer alert condition triggers after 100 5XX responses."
}
assert {
condition = google_monitoring_alert_policy.load_balancer_server_error_alerts[0].conditions[0].condition_threshold[0].aggregations[0].alignment_period == "120s"
condition = google_monitoring_alert_policy.load_balancer_server_error_alerts[0].conditions[0].condition_threshold[0].aggregations[0].alignment_period == "120s"
error_message = "Load balancer alert condition aggregates over 120s."
}
}
......@@ -77,3 +77,18 @@ resource "google_vpc_access_connector" "test" {
name = google_compute_subnetwork.test[0].name
}
}
resource "google_storage_bucket" "test_bucket" {
count = var.create_gcs_bucket ? 1 : 0
name = "${random_id.name.hex}-gcs"
project = var.project
location = "EU"
}
resource "google_storage_bucket_iam_member" "test" {
count = var.create_gcs_bucket ? 1 : 0
bucket = google_storage_bucket.test_bucket[0].name
role = "roles/storage.admin"
member = "serviceAccount:${random_id.name.hex}-run@${var.project}.iam.gserviceaccount.com"
depends_on = [google_storage_bucket.test_bucket]
}
......@@ -22,3 +22,8 @@ output "vpc_connector_id" {
description = "The ID of the VPC Access Connector object created to test VPC access for the Cloud Run service."
value = var.create_vpc_connector ? google_vpc_access_connector.test[0].id : null
}
output "gcs_bucket_name" {
description = "Storage bucket name for testing the GCS volume mount"
value = var.create_gcs_bucket ? google_storage_bucket.test_bucket[0].name : null
}
......@@ -8,6 +8,12 @@ variable "region" {
type = string
}
variable "create_gcs_bucket" {
description = "If true, gcs bucket will be deployed."
type = bool
default = false
}
variable "create_test_sql_instances" {
description = "If true, two SQL instances will be deployed for testing."
type = bool
......
......@@ -264,6 +264,10 @@ EOI
mode = optional(number)
})), [])
}))
gcs = optional(object({
bucket = string
read_only = optional(bool)
}))
cloud_sql_instance = optional(object({
instances = optional(list(string))
}))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment