Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

serverless-gclb

This module provisions a Google Cloud Load Balancer (GCLB) that sits in front of some number of regionalized Cloud Run services.

flowchart LR
    T[domain.com]
    T --> A

    A(Load Balancer)
    A  --> X
    A  --> Y
    A  --> Z

    subgraph "regional network C"
    X(Cloud Run Service)
    X -.-> L["..."]
    end

    subgraph "regional network B"
    Y(Cloud Run Service)
    Y -.-> M["..."]
    end

    subgraph "regional network A"
    Z(Cloud Run Service)
    Z -.-> N["..."]
    end
Loading
// Create a network with several regional subnets
module "networking" {
  source = "chainguard-dev/common/infra//modules/networking"

  name       = "my-networking"
  project_id = var.project_id
  regions    = [...]
}

resource "google_dns_managed_zone" "top-level-zone" {
  project     = var.project_id
  name        = "example-com"
  dns_name    = "example.com."
}

module "serverless-gclb" {
  source = "chainguard-dev/common/infra//modules/serverless-gclb"

  name       = "my-gclb"
  project_id = var.project_id
  dns_zone   = google_dns_managed_zone.top-level-zone.name

  // Regions are all of the places that we have backends deployed.
  // Regions must be removed from serving before they are torn down.
  regions         = keys(module.networking.regional-networks)
  serving_regions = keys(module.networking.regional-networks)

  public-services = {
    "foo.example.com" = {
      name = "my-foo-service" // e.g. from regional-go-service
    }
  }
}

Migrating an existing proxy to a certificate map

A target HTTPS proxy must always have at least one SSL certificate or a certificate map attached, and the Google provider updates ssl_certificates before certificate_map. Flipping an existing proxy straight from per-hostname certs to a map in a single apply therefore strips the certs before the map is attached, and GCP rejects it:

Error 412: Certificate Map or at least 1 SSL certificate must be specified
for setting SSL certificates in TargetHttpsProxy.

Use retain_managed_certificates to migrate in two applies, keeping a valid certificate source attached the whole time:

  1. Set certificate_map and retain_managed_certificates = true. Both the per-hostname certs and the map are attached; the map serves TLS.
  2. Set retain_managed_certificates = false. The per-hostname certs are dropped; the map already satisfies the proxy, so there is no gap.

Rolling back is the mirror image, and is not symmetric with a fresh deployment. Removing certificate_map recreates the per-hostname managed certs, which take 15-60+ minutes to reach ACTIVE; detach the map before they are ACTIVE and the proxy serves from provisioning certs, so TLS fails. Roll back in two applies:

  1. Set retain_managed_certificates = true. The per-hostname certs are recreated and attached alongside the still-present map, which keeps serving.
  2. Wait for the recreated certificates to report ACTIVE, then set certificate_map = "". The map is detached and the ACTIVE certs serve.

Greenfield proxies created with certificate_map set (and retain_managed_certificates left false) need none of this; they are born with only the map.

Requirements

Name Version
google >= 7.34.0

Providers

Name Version
google >= 7.34.0

Modules

No modules.

Resources

Name Type
google_compute_backend_service.public-services resource
google_compute_global_address.this resource
google_compute_global_address.this-v6 resource
google_compute_global_forwarding_rule.this resource
google_compute_global_forwarding_rule.this-v6 resource
google_compute_managed_ssl_certificate.public-service resource
google_compute_region_network_endpoint_group.regional-backends resource
google_compute_ssl_policy.ssl_policy resource
google_compute_target_https_proxy.public-service resource
google_compute_url_map.public-service resource
google_dns_record_set.public-service resource
google_dns_record_set.public-service-v6 resource
google_client_openid_userinfo.me data source

Inputs

Name Description Type Default Required
certificate_map Optional Certificate Manager certificate map id, formatted as "//certificatemanager.googleapis.com/projects/.../certificateMaps/...". When set, the HTTPS proxy serves TLS from this map and the module creates no per-hostname managed SSL certificates, escaping the 15-certificate-per-proxy limit (e.g. with a wildcard certificate). Create the map in an earlier apply than the one that sets this, so its id is known at plan time. When empty (the default), the module keeps its per-hostname managed-certificate behaviour. Migrating an existing proxy between the two modes is a two-apply operation, see retain_managed_certificates and the module README. string "" no
dns_zone The managed DNS zone in which to create record sets. string n/a yes
enable_ipv6 Enable dualstack ipv6+ipv4 support on the edge/public loadbalancer end point. When false (default), ipv4-only is deployed. bool false no
forwarding_rule_load_balancing n/a
object({
external_managed_backend_bucket_migration_state = optional(string, null)
external_managed_backend_bucket_migration_testing_percentage = optional(number, null)
load_balancing_scheme = optional(string, "EXTERNAL")
})
{} no
iap IAP configuration for the load balancer.
object({
oauth2_client_id = optional(string, null)
oauth2_client_secret = optional(string, null)
enabled = bool
})
null no
name n/a string n/a yes
notification_channels The set of notification channels to which to send alerts. list(string) [] no
product Product label to apply to the service. string "unknown" no
project_id n/a string n/a yes
public-services A map from hostnames (managed by dns_zone), to the name of the regionalized cloud run service to which the hostname should be routed. A managed SSL certificate will be created for each hostname (unless certificate_map is set), and a DNS record set will be created for each hostname pointing to the load balancer's global IP address.

external_managed_migration_state: The migration state for the load balancer, [PREPARE, TEST_BY_PERCENTAGE, and TEST_ALL_TRAFFIC].
external_managed_migration_testing_percentage: The percentage of traffic to route to new load balancer, [0, 100].
load_balancing_scheme: The default load balancing scheme to use.
map(object({
name = string
disabled = optional(bool, false)
external_managed_migration_state = optional(string, null)
external_managed_migration_testing_percentage = optional(number, null)
load_balancing_scheme = optional(string, "EXTERNAL")
connection_draining_timeout_sec = optional(number, 300)
}))
n/a yes
regions The set of regions containing backends for the load balancer (regions must be added here before they can be added as serving regions). list
[
"us-central1"
]
no
retain_managed_certificates Only meaningful when certificate_map is set. When true, the per-hostname managed SSL certificates are still created and stay attached to the HTTPS proxy alongside the certificate map, which is the legal intermediate state for migrating an existing proxy without a TLS gap. A target HTTPS proxy must always have >=1 SSL certificate or a certificate map, and the provider strips ssl_certificates before attaching the map, so flipping straight from certs to map in one apply is rejected (Error 412). Instead set certificate_map with this true in one apply (both attached), then set this back to false in a follow-up apply to drop the per-hostname certs. Roll back the same way in reverse, waiting for the recreated certs to be ACTIVE before removing the map. See the module README. Defaults to false, so greenfield proxies and existing callers are unaffected. bool false no
security-policy The security policy associated with the backend service. string null no
serving_regions The set of regions with backends suitable for serving traffic from the load balancer (regions must be removed from here before they can be removed from regions). list
[
"us-central1"
]
no
team team label to apply to the service. string n/a yes

Outputs

No outputs.