Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added build_config.service_account for google_cloudfunctions2_function #17841

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/10372.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
cloudfunctions2: added `build_config.service_account` field to `google_cloudfunctions2_function` resource
```
Original file line number Diff line number Diff line change
@@ -105,6 +105,12 @@ function exported by the module specified in source_location.`,
Description: `The runtime in which to run the function. Required when deploying a new
function, optional when updating an existing function.`,
},
"service_account": {
Type: schema.TypeString,
Computed: true,
Optional: true,
Description: `The fully-qualified name of the service account to be used for building the container.`,
},
"source": {
Type: schema.TypeList,
Optional: true,
@@ -991,6 +997,8 @@ func flattenCloudfunctions2functionBuildConfig(v interface{}, d *schema.Resource
flattenCloudfunctions2functionBuildConfigEnvironmentVariables(original["environmentVariables"], d, config)
transformed["docker_repository"] =
flattenCloudfunctions2functionBuildConfigDockerRepository(original["dockerRepository"], d, config)
transformed["service_account"] =
flattenCloudfunctions2functionBuildConfigServiceAccount(original["serviceAccount"], d, config)
return []interface{}{transformed}
}
func flattenCloudfunctions2functionBuildConfigBuild(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
@@ -1154,6 +1162,10 @@ func flattenCloudfunctions2functionBuildConfigDockerRepository(v interface{}, d
return v
}

func flattenCloudfunctions2functionBuildConfigServiceAccount(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenCloudfunctions2functionServiceConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
@@ -1597,6 +1609,13 @@ func expandCloudfunctions2functionBuildConfig(v interface{}, d tpgresource.Terra
transformed["dockerRepository"] = transformedDockerRepository
}

transformedServiceAccount, err := expandCloudfunctions2functionBuildConfigServiceAccount(original["service_account"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedServiceAccount); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["serviceAccount"] = transformedServiceAccount
}

return transformed, nil
}

@@ -1791,6 +1810,10 @@ func expandCloudfunctions2functionBuildConfigDockerRepository(v interface{}, d t
return v, nil
}

func expandCloudfunctions2functionBuildConfigServiceAccount(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandCloudfunctions2functionServiceConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
Original file line number Diff line number Diff line change
@@ -484,6 +484,122 @@ resource "google_cloudfunctions2_function" "function" {
`, context)
}

func TestAccCloudfunctions2function_cloudfunctions2BasicBuilderExample(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"project": envvar.GetTestProjectFromEnv(),
"zip_path": "./test-fixtures/function-source.zip",
"location": "us-central1",
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
ExternalProviders: map[string]resource.ExternalProvider{
"random": {},
"time": {},
},
CheckDestroy: testAccCheckCloudfunctions2functionDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccCloudfunctions2function_cloudfunctions2BasicBuilderExample(context),
},
{
ResourceName: "google_cloudfunctions2_function.function",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket", "labels", "terraform_labels"},
},
},
})
}

func testAccCloudfunctions2function_cloudfunctions2BasicBuilderExample(context map[string]interface{}) string {
return acctest.Nprintf(`
locals {
project = "%{project}" # Google Cloud Platform Project ID
}

resource "google_service_account" "account" {
account_id = "tf-test-gcf-sa%{random_suffix}"
display_name = "Test Service Account"
}

resource "google_project_iam_member" "log_writer" {
project = google_service_account.account.project
role = "roles/logging.logWriter"
member = "serviceAccount:${google_service_account.account.email}"
}

resource "google_project_iam_member" "artifact_registry_writer" {
project = google_service_account.account.project
role = "roles/artifactregistry.writer"
member = "serviceAccount:${google_service_account.account.email}"
}

resource "google_project_iam_member" "storage_object_admin" {
project = google_service_account.account.project
role = "roles/storage.objectAdmin"
member = "serviceAccount:${google_service_account.account.email}"
}

resource "google_storage_bucket" "bucket" {
name = "${local.project}-tf-test-gcf-source%{random_suffix}" # Every bucket name must be globally unique
location = "US"
uniform_bucket_level_access = true
}

resource "google_storage_bucket_object" "object" {
name = "function-source.zip"
bucket = google_storage_bucket.bucket.name
source = "%{zip_path}" # Add path to the zipped function source code
}

# builder permissions need to stablize before it can pull the source zip
resource "time_sleep" "wait_60s" {
create_duration = "60s"

depends_on = [
google_project_iam_member.log_writer,
google_project_iam_member.artifact_registry_writer,
google_project_iam_member.storage_object_admin,
]
}

resource "google_cloudfunctions2_function" "function" {
name = "tf-test-function-v2%{random_suffix}"
location = "us-central1"
description = "a new function"

build_config {
runtime = "nodejs16"
entry_point = "helloHttp" # Set the entry point
source {
storage_source {
bucket = google_storage_bucket.bucket.name
object = google_storage_bucket_object.object.name
}
}
service_account = google_service_account.account.id
}

service_config {
max_instance_count = 1
available_memory = "256M"
timeout_seconds = 60
}

depends_on = [time_sleep.wait_60s]
}

output "function_uri" {
value = google_cloudfunctions2_function.function.service_config[0].uri
}
`, context)
}

func TestAccCloudfunctions2function_cloudfunctions2SecretEnvExample(t *testing.T) {
t.Parallel()

88 changes: 88 additions & 0 deletions website/docs/r/cloudfunctions2_function.html.markdown
Original file line number Diff line number Diff line change
@@ -446,6 +446,90 @@ resource "google_cloudfunctions2_function" "function" {
}
}
```
## Example Usage - Cloudfunctions2 Basic Builder


```hcl
locals {
project = "my-project-name" # Google Cloud Platform Project ID
}

resource "google_service_account" "account" {
account_id = "gcf-sa"
display_name = "Test Service Account"
}

resource "google_project_iam_member" "log_writer" {
project = google_service_account.account.project
role = "roles/logging.logWriter"
member = "serviceAccount:${google_service_account.account.email}"
}

resource "google_project_iam_member" "artifact_registry_writer" {
project = google_service_account.account.project
role = "roles/artifactregistry.writer"
member = "serviceAccount:${google_service_account.account.email}"
}

resource "google_project_iam_member" "storage_object_admin" {
project = google_service_account.account.project
role = "roles/storage.objectAdmin"
member = "serviceAccount:${google_service_account.account.email}"
}

resource "google_storage_bucket" "bucket" {
name = "${local.project}-gcf-source" # Every bucket name must be globally unique
location = "US"
uniform_bucket_level_access = true
}

resource "google_storage_bucket_object" "object" {
name = "function-source.zip"
bucket = google_storage_bucket.bucket.name
source = "function-source.zip" # Add path to the zipped function source code
}

# builder permissions need to stablize before it can pull the source zip
resource "time_sleep" "wait_60s" {
create_duration = "60s"

depends_on = [
google_project_iam_member.log_writer,
google_project_iam_member.artifact_registry_writer,
google_project_iam_member.storage_object_admin,
]
}

resource "google_cloudfunctions2_function" "function" {
name = "function-v2"
location = "us-central1"
description = "a new function"

build_config {
runtime = "nodejs16"
entry_point = "helloHttp" # Set the entry point
source {
storage_source {
bucket = google_storage_bucket.bucket.name
object = google_storage_bucket_object.object.name
}
}
service_account = google_service_account.account.id
}

service_config {
max_instance_count = 1
available_memory = "256M"
timeout_seconds = 60
}

depends_on = [time_sleep.wait_60s]
}

output "function_uri" {
value = google_cloudfunctions2_function.function.service_config[0].uri
}
```
## Example Usage - Cloudfunctions2 Secret Env


@@ -850,6 +934,10 @@ The following arguments are supported:
(Optional)
User managed repository created in Artifact Registry optionally with a customer managed encryption key.

* `service_account` -
(Optional)
The fully-qualified name of the service account to be used for building the container.


<a name="nested_source"></a>The `source` block supports: