Skip to content

Commit b062674

Browse files
authored
Add support for Cloud Run functions by adding support to the BuildConfig V2 API field (#12760)
1 parent f7be33f commit b062674

File tree

4 files changed

+298
-0
lines changed

4 files changed

+298
-0
lines changed

mmv1/products/cloudrunv2/Service.yaml

+54
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,18 @@ examples:
161161
cloud_run_service_name: 'cloudrun-service'
162162
ignore_read_extra:
163163
- 'deletion_protection'
164+
- name: 'cloudrunv2_service_function'
165+
primary_resource_id: 'default'
166+
primary_resource_name: 'fmt.Sprintf("tf-test-cloudrun-srv%s", context["random_suffix"])'
167+
vars:
168+
cloud_run_service_name: 'cloudrun-service'
169+
bucket_name: 'gcf-source'
170+
zip_path: 'function_source.zip'
171+
sa_name: 'build-sa'
172+
test_vars_overrides:
173+
'zip_path': '"./test-fixtures/function-source.zip"'
174+
ignore_read_extra:
175+
- 'deletion_protection'
164176
virtual_fields:
165177
- name: 'deletion_protection'
166178
description: |
@@ -1119,6 +1131,48 @@ properties:
11191131
description: |-
11201132
All URLs serving traffic for this Service.
11211133
output: true
1134+
- name: 'buildConfig'
1135+
type: NestedObject
1136+
description: |-
1137+
Configuration for building a Cloud Run function.
1138+
properties:
1139+
- name: 'name'
1140+
type: String
1141+
description: |-
1142+
The Cloud Build name of the latest successful deployment of the function.
1143+
output: true
1144+
- name: 'sourceLocation'
1145+
type: String
1146+
description: |-
1147+
The Cloud Storage bucket URI where the function source code is located.
1148+
- name: 'functionTarget'
1149+
type: String
1150+
description: |-
1151+
The name of the function (as defined in source code) that will be executed. Defaults to the resource name suffix, if not specified. For backward compatibility, if function with given name is not found, then the system will try to use function named "function".
1152+
- name: 'imageUri'
1153+
type: String
1154+
description: |-
1155+
Artifact Registry URI to store the built image.
1156+
- name: 'baseImage'
1157+
type: String
1158+
description: |-
1159+
The base image used to build the function.
1160+
- name: 'enableAutomaticUpdates'
1161+
type: Boolean
1162+
description: |-
1163+
Sets whether the function will receive automatic base image updates.
1164+
- name: 'workerPool'
1165+
type: String
1166+
description: |-
1167+
Name of the Cloud Build Custom Worker Pool that should be used to build the Cloud Run function. The format of this field is `projects/{project}/locations/{region}/workerPools/{workerPool}` where {project} and {region} are the project id and region respectively where the worker pool is defined and {workerPool} is the short name of the worker pool.
1168+
- name: 'environmentVariables'
1169+
type: KeyValuePairs
1170+
description: |-
1171+
User-provided build-time environment variables for the function.
1172+
- name: 'serviceAccount'
1173+
type: String
1174+
description: |-
1175+
Service account to be used for building the container. The format of this field is `projects/{projectId}/serviceAccounts/{serviceAccountEmail}`.
11221176
- name: 'reconciling'
11231177
type: Boolean
11241178
description: |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
resource "google_cloud_run_v2_service" "{{$.PrimaryResourceId}}" {
2+
name = "{{index $.Vars "cloud_run_service_name"}}"
3+
location = "us-central1"
4+
deletion_protection = false
5+
ingress = "INGRESS_TRAFFIC_ALL"
6+
7+
template {
8+
containers {
9+
image = "us-docker.pkg.dev/cloudrun/container/hello"
10+
}
11+
}
12+
build_config {
13+
source_location = "gs://${google_storage_bucket.bucket.name}/${google_storage_bucket_object.object.name}"
14+
function_target = "helloHttp"
15+
image_uri = "us-docker.pkg.dev/cloudrun/container/hello"
16+
base_image = "us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/nodejs22"
17+
enable_automatic_updates = true
18+
worker_pool = "worker-pool"
19+
environment_variables = {
20+
FOO_KEY = "FOO_VALUE"
21+
BAR_KEY = "BAR_VALUE"
22+
}
23+
service_account = google_service_account.cloudbuild_service_account.id
24+
}
25+
depends_on = [
26+
google_project_iam_member.act_as,
27+
google_project_iam_member.logs_writer
28+
]
29+
}
30+
31+
data "google_project" "project" {
32+
}
33+
34+
resource "google_storage_bucket" "bucket" {
35+
name = "${data.google_project.project.project_id}-{{index $.Vars "bucket_name"}}" # Every bucket name must be globally unique
36+
location = "US"
37+
uniform_bucket_level_access = true
38+
}
39+
40+
resource "google_storage_bucket_object" "object" {
41+
name = "function-source.zip"
42+
bucket = google_storage_bucket.bucket.name
43+
source = "{{index $.Vars "zip_path"}}" # Add path to the zipped function source code
44+
}
45+
46+
resource "google_service_account" "cloudbuild_service_account" {
47+
account_id = "{{index $.Vars "sa_name"}}"
48+
}
49+
50+
resource "google_project_iam_member" "act_as" {
51+
project = data.google_project.project.project_id
52+
role = "roles/iam.serviceAccountUser"
53+
member = "serviceAccount:${google_service_account.cloudbuild_service_account.email}"
54+
}
55+
56+
resource "google_project_iam_member" "logs_writer" {
57+
project = data.google_project.project.project_id
58+
role = "roles/logging.logWriter"
59+
member = "serviceAccount:${google_service_account.cloudbuild_service_account.email}"
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
package cloudrunv2_test
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
"testing"
7+
8+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
9+
"github.com/hashicorp/terraform-plugin-testing/terraform"
10+
11+
"github.com/hashicorp/terraform-provider-google/google/acctest"
12+
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
13+
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
14+
)
15+
16+
func TestAccCloudRunV2Service_cloudrunv2ServiceFunctionExample_update(t *testing.T) {
17+
t.Parallel()
18+
19+
context := map[string]interface{}{
20+
"zip_path": "./test-fixtures/function-source.zip",
21+
"random_suffix": acctest.RandString(t, 10),
22+
}
23+
24+
acctest.VcrTest(t, resource.TestCase{
25+
PreCheck: func() { acctest.AccTestPreCheck(t) },
26+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
27+
CheckDestroy: testAccCheckCloudRunV2ServiceDestroyProducer(t),
28+
Steps: []resource.TestStep{
29+
{
30+
Config: testAccCloudRunV2Service_cloudrunv2ServiceFunctionExample_full(context),
31+
},
32+
{
33+
ResourceName: "google_cloud_run_v2_service.default",
34+
ImportState: true,
35+
ImportStateVerify: true,
36+
ImportStateVerifyIgnore: []string{"annotations", "deletion_protection", "labels", "location", "name", "terraform_labels"},
37+
},
38+
{
39+
Config: testAccCloudRunV2Service_cloudrunv2ServiceFunctionExample_update(context),
40+
ConfigPlanChecks: resource.ConfigPlanChecks{
41+
PreApply: []plancheck.PlanCheck{
42+
plancheck.ExpectResourceAction("google_cloud_run_v2_service.default", plancheck.ResourceActionUpdate),
43+
},
44+
},
45+
},
46+
{
47+
ResourceName: "google_cloud_run_v2_service.default",
48+
ImportState: true,
49+
ImportStateVerify: true,
50+
ImportStateVerifyIgnore: []string{"annotations", "deletion_protection", "labels", "location", "name", "terraform_labels"},
51+
},
52+
},
53+
})
54+
}
55+
56+
func testAccCloudRunV2Service_cloudrunv2ServiceFunctionExample_full(context map[string]interface{}) string {
57+
return acctest.Nprintf(`
58+
resource "google_cloud_run_v2_service" "default" {
59+
name = "tf-test-cloudrun-service%{random_suffix}"
60+
location = "us-central1"
61+
deletion_protection = false
62+
ingress = "INGRESS_TRAFFIC_ALL"
63+
64+
template {
65+
containers {
66+
image = "us-docker.pkg.dev/cloudrun/container/hello"
67+
}
68+
}
69+
build_config {
70+
source_location = "gs://${google_storage_bucket.bucket.name}/${google_storage_bucket_object.object.name}"
71+
function_target = "helloHttp"
72+
image_uri = "us-docker.pkg.dev/cloudrun/container/hello"
73+
base_image = "us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/nodejs22"
74+
enable_automatic_updates = true
75+
worker_pool = "worker-pool"
76+
environment_variables = {
77+
FOO_KEY = "FOO_VALUE"
78+
BAR_KEY = "BAR_VALUE"
79+
}
80+
service_account = google_service_account.cloudbuild_service_account.id
81+
}
82+
depends_on = [
83+
google_project_iam_member.act_as,
84+
google_project_iam_member.logs_writer
85+
]
86+
}
87+
88+
data "google_project" "project" {
89+
}
90+
91+
resource "google_storage_bucket" "bucket" {
92+
name = "${data.google_project.project.project_id}-tf-test-gcf-source%{random_suffix}" # Every bucket name must be globally unique
93+
location = "US"
94+
uniform_bucket_level_access = true
95+
}
96+
97+
resource "google_storage_bucket_object" "object" {
98+
name = "function-source.zip"
99+
bucket = google_storage_bucket.bucket.name
100+
source = "%{zip_path}" # Add path to the zipped function source code
101+
}
102+
103+
resource "google_service_account" "cloudbuild_service_account" {
104+
account_id = "tf-test-build-sa%{random_suffix}"
105+
}
106+
107+
resource "google_project_iam_member" "act_as" {
108+
project = data.google_project.project.project_id
109+
role = "roles/iam.serviceAccountUser"
110+
member = "serviceAccount:${google_service_account.cloudbuild_service_account.email}"
111+
}
112+
113+
resource "google_project_iam_member" "logs_writer" {
114+
project = data.google_project.project.project_id
115+
role = "roles/logging.logWriter"
116+
member = "serviceAccount:${google_service_account.cloudbuild_service_account.email}"
117+
}
118+
`, context)
119+
}
120+
121+
func testAccCloudRunV2Service_cloudrunv2ServiceFunctionExample_update(context map[string]interface{}) string {
122+
return acctest.Nprintf(`
123+
resource "google_cloud_run_v2_service" "default" {
124+
name = "tf-test-cloudrun-service%{random_suffix}"
125+
location = "us-central1"
126+
deletion_protection = false
127+
ingress = "INGRESS_TRAFFIC_ALL"
128+
129+
template {
130+
containers {
131+
image = "us-docker.pkg.dev/cloudrun/container/hello"
132+
}
133+
}
134+
build_config {
135+
source_location = "gs://${google_storage_bucket.bucket.name}/${google_storage_bucket_object.object.name}"
136+
function_target = "helloHttp"
137+
image_uri = "gcr.io/cloudrun/hello:latest"
138+
base_image = "us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/nodejs20"
139+
enable_automatic_updates = false
140+
worker_pool = "worker-pool-2"
141+
environment_variables = {
142+
FOO_KEY_FOO = "FOO_VALUE_FOO"
143+
BAR_KEY_BAR = "BAR_VALUE_BAR"
144+
}
145+
service_account = google_service_account.cloudbuild_service_account.id
146+
}
147+
depends_on = [
148+
google_project_iam_member.act_as,
149+
google_project_iam_member.logs_writer
150+
]
151+
}
152+
153+
data "google_project" "project" {
154+
}
155+
156+
resource "google_storage_bucket" "bucket" {
157+
name = "${data.google_project.project.project_id}-tf-test-gcf-source%{random_suffix}" # Every bucket name must be globally unique
158+
location = "US"
159+
uniform_bucket_level_access = true
160+
}
161+
162+
resource "google_storage_bucket_object" "object" {
163+
name = "function-source-updated.zip"
164+
bucket = google_storage_bucket.bucket.name
165+
source = "%{zip_path}" # Add path to the zipped function source code
166+
}
167+
168+
resource "google_service_account" "cloudbuild_service_account" {
169+
account_id = "tf-test-build-sa-updated%{random_suffix}"
170+
}
171+
172+
resource "google_project_iam_member" "act_as" {
173+
project = data.google_project.project.project_id
174+
role = "roles/iam.serviceAccountUser"
175+
member = "serviceAccount:${google_service_account.cloudbuild_service_account.email}"
176+
}
177+
178+
resource "google_project_iam_member" "logs_writer" {
179+
project = data.google_project.project.project_id
180+
role = "roles/logging.logWriter"
181+
member = "serviceAccount:${google_service_account.cloudbuild_service_account.email}"
182+
}
183+
`, context)
184+
}
Binary file not shown.

0 commit comments

Comments
 (0)