From 1b34d4b7f15c69efc9c89585097ed5cd7137d62b Mon Sep 17 00:00:00 2001 From: Modular Magician Date: Sat, 25 Jul 2020 00:58:16 +0000 Subject: [PATCH] Backend service support for internet NEG backend (#3782) * Add ability to set global network endpoint group as backend for backend service. Make health_checks optional * PR fixes * Add encoder to remove max_utilization when neg backend * Check for global NEG in group to remove max_utilization * Add another nil check * Spacing * Docs fix Signed-off-by: Modular Magician --- .changelog/3782.txt | 3 ++ google/resource_compute_backend_service.go | 51 ++++++++++++------ ..._compute_backend_service_generated_test.go | 53 +++++++++++++++++++ .../r/compute_backend_service.html.markdown | 49 ++++++++++++++--- 4 files changed, 134 insertions(+), 22 deletions(-) create mode 100644 .changelog/3782.txt diff --git a/.changelog/3782.txt b/.changelog/3782.txt new file mode 100644 index 00000000000..2ebfcb13884 --- /dev/null +++ b/.changelog/3782.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +compute: Added support to `google_compute_backend_service` for setting a network endpoint group as `backend.group` +``` diff --git a/google/resource_compute_backend_service.go b/google/resource_compute_backend_service.go index a522103b8c4..be2bc89be2f 100644 --- a/google/resource_compute_backend_service.go +++ b/google/resource_compute_backend_service.go @@ -20,6 +20,7 @@ import ( "log" "reflect" "strconv" + "strings" "time" "github.com/hashicorp/errwrap" @@ -163,21 +164,6 @@ func resourceComputeBackendService() *schema.Resource { SchemaVersion: 1, Schema: map[string]*schema.Schema{ - "health_checks": { - Type: schema.TypeSet, - Required: true, - Description: `The set of URLs to the HttpHealthCheck or HttpsHealthCheck resource -for health checking this BackendService. Currently at most one health -check can be specified, and a health check is required. - -For internal load balancing, a URL to a HealthCheck resource must be specified instead.`, - MinItems: 1, - MaxItems: 1, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - Set: selfLinkRelativePathHash, - }, "name": { Type: schema.TypeString, Required: true, @@ -466,6 +452,23 @@ requests.`, Optional: true, Description: `If true, enable Cloud CDN for this BackendService.`, }, + "health_checks": { + Type: schema.TypeSet, + Optional: true, + Description: `The set of URLs to the HttpHealthCheck or HttpsHealthCheck resource +for health checking this BackendService. Currently at most one health +check can be specified. + +A health check must be specified unless the backend service uses an internet NEG as a backend. + +For internal load balancing, a URL to a HealthCheck resource must be specified instead.`, + MinItems: 1, + MaxItems: 1, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Set: selfLinkRelativePathHash, + }, "iap": { Type: schema.TypeList, Optional: true, @@ -3128,6 +3131,24 @@ func resourceComputeBackendServiceEncoder(d *schema.ResourceData, meta interface obj["iap"] = iap } + backendsRaw, ok := obj["backends"] + if !ok { + return obj, nil + } + backends := backendsRaw.([]interface{}) + for _, backendRaw := range backends { + backend := backendRaw.(map[string]interface{}) + backendGroup, ok := backend["group"] + if !ok { + continue + } + if strings.Contains(backendGroup.(string), "global/networkEndpointGroups") { + // Remove `max_utilization` from any backend that belongs to a global NEG. This field + // has a default value and causes API validation errors + backend["maxUtilization"] = nil + } + } + return obj, nil } diff --git a/google/resource_compute_backend_service_generated_test.go b/google/resource_compute_backend_service_generated_test.go index 1fcba50291e..734bb06fc0d 100644 --- a/google/resource_compute_backend_service_generated_test.go +++ b/google/resource_compute_backend_service_generated_test.go @@ -63,6 +63,59 @@ resource "google_compute_http_health_check" "default" { `, context) } +func TestAccComputeBackendService_backendServiceNetworkEndpointExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeBackendServiceDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeBackendService_backendServiceNetworkEndpointExample(context), + }, + { + ResourceName: "google_compute_backend_service.default", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccComputeBackendService_backendServiceNetworkEndpointExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_global_network_endpoint_group" "external_proxy" { + name = "tf-test-network-endpoint%{random_suffix}" + network_endpoint_type = "INTERNET_FQDN_PORT" + default_port = "443" +} + +resource "google_compute_global_network_endpoint" "proxy" { + global_network_endpoint_group = google_compute_global_network_endpoint_group.external_proxy.id + fqdn = "test.example.com" + port = google_compute_global_network_endpoint_group.external_proxy.default_port +} + +resource "google_compute_backend_service" "default" { + name = "tf-test-backend-service%{random_suffix}" + enable_cdn = true + timeout_sec = 10 + connection_draining_timeout_sec = 10 + + custom_request_headers = ["host: ${google_compute_global_network_endpoint.proxy.fqdn}"] + + backend { + group = google_compute_global_network_endpoint_group.external_proxy.id + } +} +`, context) +} + func testAccCheckComputeBackendServiceDestroyProducer(t *testing.T) func(s *terraform.State) error { return func(s *terraform.State) error { for name, rs := range s.RootModule().Resources { diff --git a/website/docs/r/compute_backend_service.html.markdown b/website/docs/r/compute_backend_service.html.markdown index c130ba75989..2b4674c104f 100644 --- a/website/docs/r/compute_backend_service.html.markdown +++ b/website/docs/r/compute_backend_service.html.markdown @@ -131,19 +131,46 @@ resource "google_compute_health_check" "health_check" { } } ``` + +## Example Usage - Backend Service Network Endpoint + + +```hcl +resource "google_compute_global_network_endpoint_group" "external_proxy" { + name = "network-endpoint" + network_endpoint_type = "INTERNET_FQDN_PORT" + default_port = "443" +} + +resource "google_compute_global_network_endpoint" "proxy" { + global_network_endpoint_group = google_compute_global_network_endpoint_group.external_proxy.id + fqdn = "test.example.com" + port = google_compute_global_network_endpoint_group.external_proxy.default_port +} + +resource "google_compute_backend_service" "default" { + name = "backend-service" + enable_cdn = true + timeout_sec = 10 + connection_draining_timeout_sec = 10 + + custom_request_headers = ["host: ${google_compute_global_network_endpoint.proxy.fqdn}"] + + backend { + group = google_compute_global_network_endpoint_group.external_proxy.id + } +} +``` ## Argument Reference The following arguments are supported: -* `health_checks` - - (Required) - The set of URLs to the HttpHealthCheck or HttpsHealthCheck resource - for health checking this BackendService. Currently at most one health - check can be specified, and a health check is required. - For internal load balancing, a URL to a HealthCheck resource must be specified instead. - * `name` - (Required) Name of the resource. Provided by the client when the resource is @@ -208,6 +235,14 @@ The following arguments are supported: (Optional) If true, enable Cloud CDN for this BackendService. +* `health_checks` - + (Optional) + The set of URLs to the HttpHealthCheck or HttpsHealthCheck resource + for health checking this BackendService. Currently at most one health + check can be specified. + A health check must be specified unless the backend service uses an internet NEG as a backend. + For internal load balancing, a URL to a HealthCheck resource must be specified instead. + * `iap` - (Optional) Settings for enabling Cloud Identity Aware Proxy Structure is documented below.