Skip to content

Commit

Permalink
added build_config.service_account for google_cloudfunctions2_functio…
Browse files Browse the repository at this point in the history
…n (#10372) (hashicorp#7231)

[upstream:eeabeacf109985bd942f2555da970ac6676f4893]

Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
modular-magician authored Apr 12, 2024
1 parent d79271b commit c89b699
Show file tree
Hide file tree
Showing 4 changed files with 230 additions and 0 deletions.
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
Expand Up @@ -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,
Expand Down Expand Up @@ -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{} {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
88 changes: 88 additions & 0 deletions website/docs/r/cloudfunctions2_function.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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:

Expand Down

0 comments on commit c89b699

Please sign in to comment.