Google Cloud Internal HTTP(S) Load Balancers now have global access support

Previously, the envoy-based Internal HTTP(S) load balancers could only be accessed within the same region. For orgs that leverage multiple regions and perform cross-region traffic, this limitation was a real pain point, and not a problem for AWS ALBs. So, I’m glad to see it’s now offered:

Oddly, the radio button only shows up during the ILB creation. To modify an existing one, use this gcloud command:

gcloud compute forwarding-rules update NAME --allow-global-access

Or, in Terraform:

resource "google_compute_forwarding_rule" "default" {
  allow_global_access   = true
}

It’s also important to be aware that Global access on the HTTP(S) ILB must be enabled if accessing from another load balancer via PSC. If not, you’ll get this error message:

 Error 400: Invalid value for field 'resource.backends[0]': '{  "resourceGroup": "projects/myproject/regions/us-west1/networkEndpointGroups/psc-backend", ...'. Global L7 Private Service Connect consumers require the Private Service Connect producer load b
alancer to have AllowGlobalAccess enabled., invalid

Advertisement

Using the Built-in GeoIP Functionality of GCP HTTP/HTTPS Load Balancers

GCP HTTP/HTTPS Load Balancers offer great performance, and today I learned of a cool almost hidden feature: the ability to stamp custom headers with client GeoIP info. Here’s a Terraform config snippet:

resource "google_compute_backend_service" "MY_BACKEND_SERVICE" {
  provider                 = google-beta
  name                     = "my-backend-service"
  health_checks            = [ google_compute_health_check.MY_HEALTHCHECK.id ]
  backed {
    group                  = google_compute_instance_group.MY_INSTANCE_GROUP.self_link
    balancing_mode         = "UTILIZATION"
    max_utilization        = 1.0
  }
  custom_request_headers   = [ "X-Client-Geo-Location: {client_region},{client_city}" ]
  custom_response_headers  = [ "X-Cache-Hit: {cdn_cache_status}" ]
}

This will cause the Backend Service to stamp all HTTP requests with a custom header called “X-Client-Geo-Location” with the country abbreviation and city. It can then be parsed on the server to get this information for the client without having to rely on messy X-Forwarded-For parsing and GeoIP lookups.

Here’s a Python example that redirects the user to UK or Australia localized websites:

#!/usr/bin/env python3

import os

try:
   client_location = os.environ.get('HTTP_X_CLIENT_GEO_LOCATION', None)
   if client_location:
       [country,city] = client_location.split(',')
   websites = { 'UK': "www.foo.co.uk", 'AU': "www.foo.au" }
   if country in websites:
       local_website = websites[country]
   else:
       local_website = "www.foo.com"
   print("Status: 301\nLocation: https://{}\n".format(local_website))

except Exception as e:
   print("Status: 500\nContent-Type: text/plain\n\n{}".format(e))

GCP Load Balancers – Two Gotchas

Healthchecks are failing, even though the service is running and open via fw rules

Healthchecks actually originate from GCP directly, rather than the load balancer instance itself.  So these networks must be whitelisted in the firewall rules:

  • 35.191.0.0/16
  • 130.211.0.0/22

The LB works in the same region, but does not respond from different regions

By default, load balancers operate in regional-only mode.  To switch to global, edit the frontend properties and look for this radio button:

ilb_global_access