diff --git a/templates/terraform/examples/cloud_run_domain_mapping_basic.tf.erb b/templates/terraform/examples/cloud_run_domain_mapping_basic.tf.erb index 408108952843..6d5e31461860 100644 --- a/templates/terraform/examples/cloud_run_domain_mapping_basic.tf.erb +++ b/templates/terraform/examples/cloud_run_domain_mapping_basic.tf.erb @@ -10,7 +10,7 @@ resource "google_cloud_run_service" "<%= ctx[:primary_resource_id] %>" { template { spec { containers { - image = "gcr.io/cloudrun/hello" + image = "us-docker.pkg.dev/cloudrun/container/hello" } } } diff --git a/templates/terraform/examples/cloud_run_service_basic.tf.erb b/templates/terraform/examples/cloud_run_service_basic.tf.erb index d68649fa73e6..73d3011c6d68 100644 --- a/templates/terraform/examples/cloud_run_service_basic.tf.erb +++ b/templates/terraform/examples/cloud_run_service_basic.tf.erb @@ -5,7 +5,7 @@ resource "google_cloud_run_service" "<%= ctx[:primary_resource_id] %>" { template { spec { containers { - image = "gcr.io/cloudrun/hello" + image = "us-docker.pkg.dev/cloudrun/container/hello" } } } diff --git a/templates/terraform/examples/cloud_run_service_multiple_environment_variables.tf.erb b/templates/terraform/examples/cloud_run_service_multiple_environment_variables.tf.erb index 0607250f4103..d671ba75451e 100644 --- a/templates/terraform/examples/cloud_run_service_multiple_environment_variables.tf.erb +++ b/templates/terraform/examples/cloud_run_service_multiple_environment_variables.tf.erb @@ -5,7 +5,7 @@ resource "google_cloud_run_service" "<%= ctx[:primary_resource_id] %>" { template { spec { containers { - image = "gcr.io/cloudrun/hello" + image = "us-docker.pkg.dev/cloudrun/container/hello" env { name = "SOURCE" value = "remote" diff --git a/templates/terraform/examples/cloud_run_service_noauth.tf.erb b/templates/terraform/examples/cloud_run_service_noauth.tf.erb index aa4edc47eca7..3a88da984e44 100644 --- a/templates/terraform/examples/cloud_run_service_noauth.tf.erb +++ b/templates/terraform/examples/cloud_run_service_noauth.tf.erb @@ -5,7 +5,7 @@ resource "google_cloud_run_service" "<%= ctx[:primary_resource_id] %>" { template { spec { containers { - image = "gcr.io/cloudrun/hello" + image = "us-docker.pkg.dev/cloudrun/container/hello" } } } diff --git a/templates/terraform/examples/cloud_run_service_sql.tf.erb b/templates/terraform/examples/cloud_run_service_sql.tf.erb index c67522d4bbd4..7762e5ed75aa 100644 --- a/templates/terraform/examples/cloud_run_service_sql.tf.erb +++ b/templates/terraform/examples/cloud_run_service_sql.tf.erb @@ -5,7 +5,7 @@ resource "google_cloud_run_service" "<%= ctx[:primary_resource_id] %>" { template { spec { containers { - image = "gcr.io/cloudrun/hello" + image = "us-docker.pkg.dev/cloudrun/container/hello" } } diff --git a/templates/terraform/examples/cloud_run_service_traffic_split.tf.erb b/templates/terraform/examples/cloud_run_service_traffic_split.tf.erb index b3dcffce5a0a..c6d57b3b0ffd 100644 --- a/templates/terraform/examples/cloud_run_service_traffic_split.tf.erb +++ b/templates/terraform/examples/cloud_run_service_traffic_split.tf.erb @@ -5,7 +5,7 @@ resource "google_cloud_run_service" "<%= ctx[:primary_resource_id] %>" { template { spec { containers { - image = "gcr.io/cloudrun/hello" + image = "us-docker.pkg.dev/cloudrun/container/hello" } } metadata { diff --git a/templates/terraform/examples/region_network_endpoint_group_cloudrun.tf.erb b/templates/terraform/examples/region_network_endpoint_group_cloudrun.tf.erb index e5c0e597c0cc..7dd4bad620a7 100644 --- a/templates/terraform/examples/region_network_endpoint_group_cloudrun.tf.erb +++ b/templates/terraform/examples/region_network_endpoint_group_cloudrun.tf.erb @@ -15,7 +15,7 @@ resource "google_cloud_run_service" "<%= ctx[:primary_resource_id] %>" { template { spec { containers { - image = "gcr.io/cloudrun/hello" + image = "us-docker.pkg.dev/cloudrun/container/hello" } } } diff --git a/third_party/terraform/data_sources/data_source_cloud_run_locations.go b/third_party/terraform/data_sources/data_source_cloud_run_locations.go new file mode 100644 index 000000000000..69df596e7313 --- /dev/null +++ b/third_party/terraform/data_sources/data_source_cloud_run_locations.go @@ -0,0 +1,81 @@ +package google + +import ( + "fmt" + "log" + "sort" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceGoogleCloudRunLocations() *schema.Resource { + return &schema.Resource{ + Read: dataSourceGoogleCloudRunLocationsRead, + Schema: map[string]*schema.Schema{ + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "locations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + } +} + +func dataSourceGoogleCloudRunLocationsRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "https://run.googleapis.com/v1/projects/{{project}}/locations") + if err != nil { + return err + } + + res, err := sendRequest(config, "GET", project, url, userAgent, nil) + if err != nil { + return fmt.Errorf("Error listing Cloud Run Locations : %s", err) + } + + locationsRaw := flattenCloudRunLocations(res) + + locations := make([]string, len(locationsRaw)) + for i, loc := range locationsRaw { + locations[i] = loc.(string) + } + sort.Strings(locations) + + log.Printf("[DEBUG] Received Google Cloud Run Locations: %q", locations) + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error setting project: %s", err) + } + if err := d.Set("locations", locations); err != nil { + return fmt.Errorf("Error setting location: %s", err) + } + + d.SetId(fmt.Sprintf("projects/%s", project)) + + return nil +} + +func flattenCloudRunLocations(resp map[string]interface{}) []interface{} { + regionList := resp["locations"].([]interface{}) + regions := make([]interface{}, len(regionList)) + for i, v := range regionList { + regionObj := v.(map[string]interface{}) + regions[i] = regionObj["locationId"] + } + return regions +} diff --git a/third_party/terraform/tests/data_source_cloud_run_locations_test.go b/third_party/terraform/tests/data_source_cloud_run_locations_test.go new file mode 100644 index 000000000000..eb997a547321 --- /dev/null +++ b/third_party/terraform/tests/data_source_cloud_run_locations_test.go @@ -0,0 +1,67 @@ +package google + +import ( + "errors" + "fmt" + "strconv" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccDataSourceGoogleCloudRunLocations_basic(t *testing.T) { + t.Parallel() + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceGoogleCloudRunLocationsBasic, + Check: resource.ComposeTestCheckFunc( + testAccCheckGoogleCloudRunLocations("data.google_cloud_run_locations.default"), + ), + }, + }, + }) +} + +func testAccCheckGoogleCloudRunLocations(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Can't find cloud run locations data source: %s", n) + } + + if rs.Primary.ID == "" { + return errors.New("data source id not set") + } + + count, ok := rs.Primary.Attributes["locations.#"] + if !ok { + return errors.New("can't find 'locations' attribute") + } + + cnt, err := strconv.Atoi(count) + if err != nil { + return errors.New("failed to read number of locations") + } + if cnt < 5 { + return fmt.Errorf("expected at least 5 locations, received %d, this is most likely a bug", cnt) + } + + for i := 0; i < cnt; i++ { + idx := fmt.Sprintf("locations.%d", i) + _, ok := rs.Primary.Attributes[idx] + if !ok { + return fmt.Errorf("expected %q, location not found", idx) + } + } + return nil + } +} + +const testAccDataSourceGoogleCloudRunLocationsBasic = ` +data "google_cloud_run_locations" "default" {} +` diff --git a/third_party/terraform/tests/data_source_tpu_tensorflow_versions_test.go b/third_party/terraform/tests/data_source_tpu_tensorflow_versions_test.go index 0c601dee8f54..1398a99d8b8b 100644 --- a/third_party/terraform/tests/data_source_tpu_tensorflow_versions_test.go +++ b/third_party/terraform/tests/data_source_tpu_tensorflow_versions_test.go @@ -35,12 +35,12 @@ func testAccCheckGoogleTpuTensorflowVersions(n string) resource.TestCheckFunc { } if rs.Primary.ID == "" { - return errors.New("data source ID not set.") + return errors.New("data source id not set") } count, ok := rs.Primary.Attributes["versions.#"] if !ok { - return errors.New("can't find 'names' attribute") + return errors.New("can't find 'versions' attribute") } cnt, err := strconv.Atoi(count) diff --git a/third_party/terraform/utils/provider.go.erb b/third_party/terraform/utils/provider.go.erb index 4558c7b3b131..e075d8e17a0b 100644 --- a/third_party/terraform/utils/provider.go.erb +++ b/third_party/terraform/utils/provider.go.erb @@ -182,6 +182,7 @@ func Provider() *schema.Provider { "google_cloudfunctions_function": dataSourceGoogleCloudFunctionsFunction(), "google_cloud_identity_groups": dataSourceGoogleCloudIdentityGroups(), "google_cloud_identity_group_memberships": dataSourceGoogleCloudIdentityGroupMemberships(), + "google_cloud_run_locations": dataSourceGoogleCloudRunLocations(), "google_cloud_run_service": dataSourceGoogleCloudRunService(), "google_composer_environment": dataSourceGoogleComposerEnvironment(), "google_composer_image_versions": dataSourceGoogleComposerImageVersions(), @@ -191,7 +192,7 @@ func Provider() *schema.Provider { "google_compute_default_service_account": dataSourceGoogleComputeDefaultServiceAccount(), "google_compute_forwarding_rule": dataSourceGoogleComputeForwardingRule(), "google_compute_global_address": dataSourceGoogleComputeGlobalAddress(), - "google_compute_global_forwarding_rule": dataSourceGoogleComputeGlobalForwardingRule(), + "google_compute_global_forwarding_rule": dataSourceGoogleComputeGlobalForwardingRule(), "google_compute_image": dataSourceGoogleComputeImage(), "google_compute_instance": dataSourceGoogleComputeInstance(), "google_compute_instance_serial_port": dataSourceGoogleComputeInstanceSerialPort(), diff --git a/third_party/terraform/website/docs/d/cloud_run_locations.html.markdown b/third_party/terraform/website/docs/d/cloud_run_locations.html.markdown new file mode 100644 index 000000000000..e6ea97360547 --- /dev/null +++ b/third_party/terraform/website/docs/d/cloud_run_locations.html.markdown @@ -0,0 +1,79 @@ +--- +subcategory: "Cloud Run" +layout: "google" +page_title: "Google: google_cloud_run_locations" +sidebar_current: "docs-google-datasource-cloud-run-locations" +description: |- + Get Cloud Run locations available for a project. +--- + +# google\_cloud\_run\_locations + +Get Cloud Run locations available for a project. + +To get more information about Cloud Run, see: + +* [API documentation](https://cloud.google.com/run/docs/reference/rest/v1/projects.locations) +* How-to Guides + * [Official Documentation](https://cloud.google.com/run/docs/) + +## Example Usage + +```hcl +data "google_cloud_run_locations" "available" { +} +``` + +## Example Usage: Multi-regional Cloud Run deployment + +```hcl +data "google_cloud_run_locations" "available" { +} + +resource "google_cloud_run_service" "service_one" { + name = "service-one" + location = data.google_cloud_run_locations.available.locations[0] + + template { + spec { + containers { + image = "us-docker.pkg.dev/cloudrun/container/hello" + } + } + } + traffic { + percent = 100 + latest_revision = true + } +} + +resource "google_cloud_run_service" "service_two" { + name = "service-two" + location = data.google_cloud_run_locations.available.locations[1] + + template { + spec { + containers { + image = "us-docker.pkg.dev/cloudrun/container/hello"" + } + } + } + traffic { + percent = 100 + latest_revision = true + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `project` - (Optional) The project to list versions for. If it + is not provided, the provider project is used. + +## Attributes Reference + +The following attributes are exported: + +* `locations` - The list of Cloud Run locations available for the given project.