From fce153549b703658df13f46be39c3cc0bbaef019 Mon Sep 17 00:00:00 2001 From: Maciek Wasilewski Date: Thu, 3 Sep 2026 08:48:59 +0000 Subject: [PATCH] Support attaching regional backend bucket to google_compute_region_url_map Fixes https://github.com/hashicorp/terraform-provider-google/issues/26894 ```release-note:enhancement compute: added support for attaching `google_compute_region_backend_bucket` to `google_compute_region_url_map` ``` --- mmv1/products/compute/RegionUrlMap.yaml | 55 +++++++++++------- .../reference_to_region_backend.tmpl | 57 +++++++++++++++++++ .../region_url_map_backend_bucket.tf.tmpl | 42 ++++++++++++++ 3 files changed, 132 insertions(+), 22 deletions(-) create mode 100644 mmv1/templates/terraform/custom_expand/reference_to_region_backend.tmpl create mode 100644 mmv1/templates/terraform/samples/services/compute/region_url_map_backend_bucket.tf.tmpl diff --git a/mmv1/products/compute/RegionUrlMap.yaml b/mmv1/products/compute/RegionUrlMap.yaml index d00a9bacb482..277d04053d61 100644 --- a/mmv1/products/compute/RegionUrlMap.yaml +++ b/mmv1/products/compute/RegionUrlMap.yaml @@ -278,6 +278,16 @@ samples: home_backend_service_name: '"home" + randomSuffix' # for backward compatible mirror_backend_service_name: '"mirror" + randomSuffix' + - name: 'region_url_map_backend_bucket' + primary_resource_id: 'regionurlmap' + min_version: 'beta' + steps: + - name: 'region_url_map_backend_bucket' + min_version: 'beta' + resource_id_vars: + region_url_map_name: 'regionurlmap' + backend_bucket_name: 'static' + storage_bucket_name: 'static' parameters: - name: 'region' type: ResourceRef @@ -305,11 +315,12 @@ properties: weightedBackendServices. Conversely, if routeAction specifies any weightedBackendServices, service must not be specified. Only one of defaultService, defaultUrlRedirect or defaultRouteAction.weightedBackendService must be set. + Can refer to a RegionBackendService or RegionBackendBucket. exactly_one_of: - 'default_service' - 'default_url_redirect' - 'default_route_action.0.weighted_backend_services' - custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.tmpl' + custom_expand: 'templates/terraform/custom_expand/reference_to_region_backend.tmpl' resource: 'RegionBackendService' imports: 'selfLink' - name: 'description' @@ -439,10 +450,10 @@ properties: - name: 'defaultService' type: ResourceRef description: | - A reference to a RegionBackendService resource. This will be used if + A reference to a RegionBackendService or RegionBackendBucket resource. This will be used if none of the pathRules defined by this PathMatcher is matched by the URL's path portion. - custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.tmpl' + custom_expand: 'templates/terraform/custom_expand/reference_to_region_backend.tmpl' # TODO: (mbang) won't work for array path matchers yet, uncomment here once they are supported. # (github.com/hashicorp/terraform-plugin-sdk/issues/470) # TODO: add defaultRouteAction.weightedBackendService here once they are supported. @@ -494,14 +505,14 @@ properties: - name: 'service' type: ResourceRef description: | - The region backend service resource to which traffic is + The RegionBackendService or RegionBackendBucket resource to which traffic is directed if this rule is matched. If routeAction is additionally specified, advanced routing actions like URL Rewrites, etc. take effect prior to sending the request to the backend. However, if service is specified, routeAction cannot contain any weightedBackendService s. Conversely, if routeAction specifies any weightedBackendServices, service must not be specified. Only one of urlRedirect, service or routeAction.weightedBackendService must be set. - custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.tmpl' + custom_expand: 'templates/terraform/custom_expand/reference_to_region_backend.tmpl' resource: 'RegionBackendService' imports: 'selfLink' - name: 'headerAction' @@ -928,7 +939,7 @@ properties: description: | The RegionBackendService resource being mirrored to. required: true - custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.tmpl' + custom_expand: 'templates/terraform/custom_expand/reference_to_region_backend.tmpl' resource: 'RegionBackendService' imports: 'selfLink' - name: 'mirrorPercent' @@ -1069,7 +1080,7 @@ properties: forwarding the request to backendService, the loadbalancer applies any relevant headerActions specified as part of this backendServiceWeight. required: true - custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.tmpl' + custom_expand: 'templates/terraform/custom_expand/reference_to_region_backend.tmpl' resource: 'RegionBackendService' imports: 'selfLink' - name: 'headerAction' @@ -1237,14 +1248,14 @@ properties: - name: 'service' type: ResourceRef description: | - The region backend service resource to which traffic is + The RegionBackendService or RegionBackendBucket resource to which traffic is directed if this rule is matched. If routeAction is additionally specified, advanced routing actions like URL Rewrites, etc. take effect prior to sending the request to the backend. However, if service is specified, routeAction cannot contain any weightedBackendService s. Conversely, if routeAction specifies any weightedBackendServices, service must not be specified. Only one of urlRedirect, service or routeAction.weightedBackendService must be set. - custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.tmpl' + custom_expand: 'templates/terraform/custom_expand/reference_to_region_backend.tmpl' resource: 'RegionBackendService' imports: 'selfLink' - name: 'paths' @@ -1398,7 +1409,7 @@ properties: description: | The RegionBackendService resource being mirrored to. required: true - custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.tmpl' + custom_expand: 'templates/terraform/custom_expand/reference_to_region_backend.tmpl' resource: 'RegionBackendService' imports: 'selfLink' - name: 'mirrorPercent' @@ -1521,7 +1532,7 @@ properties: forwarding the request to backendService, the loadbalancer applies any relevant headerActions specified as part of this backendServiceWeight. required: true - custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.tmpl' + custom_expand: 'templates/terraform/custom_expand/reference_to_region_backend.tmpl' resource: 'RegionBackendService' imports: 'selfLink' - name: 'headerAction' @@ -1784,11 +1795,11 @@ properties: - name: 'backendService' type: ResourceRef description: | - The full or partial URL to the default BackendService resource. Before forwarding the + The full or partial URL to the default RegionBackendService resource. Before forwarding the request to backendService, the loadbalancer applies any relevant headerActions specified as part of this backendServiceWeight. - custom_expand: 'templates/terraform/custom_expand/reference_to_backend.tmpl' - resource: 'BackendService' + custom_expand: 'templates/terraform/custom_expand/reference_to_region_backend.tmpl' + resource: 'RegionBackendService' imports: 'selfLink' - name: 'weight' type: Integer @@ -2011,10 +2022,10 @@ properties: - name: 'backendService' type: ResourceRef description: | - The full or partial URL to the BackendService resource being mirrored to. + The full or partial URL to the RegionBackendService resource being mirrored to. required: true - custom_expand: 'templates/terraform/custom_expand/reference_to_backend.tmpl' - resource: 'BackendService' + custom_expand: 'templates/terraform/custom_expand/reference_to_region_backend.tmpl' + resource: 'RegionBackendService' imports: 'selfLink' - name: 'mirrorPercent' min_version: beta @@ -2157,9 +2168,9 @@ properties: required: true - name: 'service' type: ResourceRef - description: A reference to expected RegionBackendService resource the given URL should be mapped to. + description: A reference to expected RegionBackendService or RegionBackendBucket resource the given URL should be mapped to. required: true - custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.tmpl' + custom_expand: 'templates/terraform/custom_expand/reference_to_region_backend.tmpl' resource: 'RegionBackendService' imports: 'selfLink' - name: 'defaultUrlRedirect' @@ -2268,8 +2279,8 @@ properties: - name: 'backendService' type: ResourceRef description: | - The full or partial URL to the default BackendService resource. Before forwarding the request to backendService, the load balancer applies any relevant headerActions specified as part of this backendServiceWeight. - custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.tmpl' + The full or partial URL to the default RegionBackendService resource. Before forwarding the request to backendService, the load balancer applies any relevant headerActions specified as part of this backendServiceWeight. + custom_expand: 'templates/terraform/custom_expand/reference_to_region_backend.tmpl' resource: 'RegionBackendService' imports: 'selfLink' - name: 'weight' @@ -2500,7 +2511,7 @@ properties: The full or partial URL to the RegionBackendService resource being mirrored to. The backend service configured for a mirroring policy must reference backends that are of the same type as the original backend service matched in the URL map. Serverless NEG backends are not currently supported as a mirrored backend service. - custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.tmpl' + custom_expand: 'templates/terraform/custom_expand/reference_to_region_backend.tmpl' resource: 'RegionBackendService' imports: 'selfLink' - name: 'mirrorPercent' diff --git a/mmv1/templates/terraform/custom_expand/reference_to_region_backend.tmpl b/mmv1/templates/terraform/custom_expand/reference_to_region_backend.tmpl new file mode 100644 index 000000000000..9aee788feb19 --- /dev/null +++ b/mmv1/templates/terraform/custom_expand/reference_to_region_backend.tmpl @@ -0,0 +1,57 @@ +{{/* + The license inside this block applies to this file + Copyright 2026 Google Inc. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ -}} +{{/* This provides the best long-form self link possible given the input for regional resources. + If the input is a full URL including scheme, we return it unmodified + https://compute.googleapis.com/v1/projects/foo/regions/bar/backendBuckets/baz -> (the same) + If the input is a partial self-link, we return it with the compute base path in front. + projects/foo/regions/bar/backendBuckets/baz -> https://compute.googleapis.com/v1/projects/foo/regions/bar/backendBuckets/baz + If the input is an even-more-partial link (not including projects), we return it with the compute base path + and the specified project in front + regions/bar/backendBuckets/baz -> https://compute.googleapis.com/v1/projects/provider-project/regions/bar/backendBuckets/baz + If the input is just name, we treat it like a regional backendService in the current region. */ -}} +func expand{{$.GetPrefix}}{{$.TitlelizeProperty}}(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + // This method returns a full self link from whatever the input is. + if v == nil || v.(string) == "" { + // It does not try to construct anything from empty. + return "", nil + } else if strings.HasPrefix(v.(string), "https://") { + // Anything that starts with a URL scheme is assumed to be a self link worth using. + return v, nil + } else if strings.HasPrefix(v.(string), "projects/") { + // If the self link references a project, we'll just stick the compute prefix on it + url, err := tpgresource.ReplaceVars(d, config, "{{"{{"}}ComputeBasePath{{"}}"}}" + v.(string)) + if err != nil { + return "", err + } + return url, nil + } else if strings.HasPrefix(v.(string), "regions/") || strings.HasPrefix(v.(string), "zones/") { + // For regional or zonal resources which include their region or zone, just put the project in front. + url, err := tpgresource.ReplaceVars(d, config, "{{"{{"}}ComputeBasePath{{"}}"}}projects/{{"{{"}}project{{"}}"}}/") + if err != nil { + return nil, err + } + return url + v.(string), nil + } + // Anything else is assumed to be a reference to a regional backend service. + f, err := tpgresource.ParseRegionalFieldValue("backendServices", v.(string), "project", "region", "zone", d, config, true) + if err != nil { + return "", err + } + + {{- if $.ResourceMetadata.ProductMetadata.IsTgcCompiler }} + url := tgcresource.GetFullUrl(config, f.RelativeLink(), "{{$.ResourceMetadata.CaiProductLegacyBaseUrl}}") + return url, nil + {{- else }} + return f.RelativeLink(), nil + {{- end }} +} diff --git a/mmv1/templates/terraform/samples/services/compute/region_url_map_backend_bucket.tf.tmpl b/mmv1/templates/terraform/samples/services/compute/region_url_map_backend_bucket.tf.tmpl new file mode 100644 index 000000000000..a31abe704aad --- /dev/null +++ b/mmv1/templates/terraform/samples/services/compute/region_url_map_backend_bucket.tf.tmpl @@ -0,0 +1,42 @@ +resource "google_compute_region_url_map" "{{$.PrimaryResourceId}}" { + name = "{{index $.ResourceIdVars "region_url_map_name"}}" + region = "us-central1" + description = "a description" + default_service = google_compute_region_backend_bucket.static.id + + host_rule { + hosts = ["mysite.com"] + path_matcher = "mysite" + } + + path_matcher { + name = "mysite" + default_service = google_compute_region_backend_bucket.static.id + + path_rule { + paths = ["/static/*"] + service = google_compute_region_backend_bucket.static.id + } + } + + test { + service = google_compute_region_backend_bucket.static.id + host = "mysite.com" + path = "/static/test" + } +} + +resource "google_compute_region_backend_bucket" "static" { + name = "{{index $.ResourceIdVars "backend_bucket_name"}}" + region = "us-central1" + bucket_name = google_storage_bucket.static.name + load_balancing_scheme = "INTERNAL_MANAGED" + description = "Regional backend bucket for static content" +} + +resource "google_storage_bucket" "static" { + name = "{{index $.ResourceIdVars "storage_bucket_name"}}" + location = "US-CENTRAL1" + force_destroy = true + uniform_bucket_level_access = true +}