Skip to content

Latest commit

 

History

History
 
 

net-ilb-l7

Internal (HTTP/S) Load Balancer Module

The module allows managing Internal HTTP/HTTPS Load Balancers (HTTP(S) ILBs), integrating the forwarding rule, the url-map, the backends, optional health checks and SSL certificates. It's designed to be a simple match for the vpc and the compute-mig modules, which can be used to manage VPCs and instance groups.

Examples

Minimal Example

An HTTP ILB with a backend service pointing to a GCE instance group:

module "ilb" {
  source     = "./modules/net-ilb-l7"
  name       = "ilb-test"
  project_id = var.project_id
  region     = "europe-west1"
  network    = var.vpc.self_link
  subnetwork = var.subnet.self_link

  backend_services_config = {
    my-backend-svc = {
      backends = [
        {
          group   = "projects/my-project/zones/europe-west1-a/instanceGroups/my-ig"
          options = null
        }
      ]
      health_checks = []
      log_config = null
      options = null
    }
  }
}
# tftest modules=1 resources=5

Network and subnetwork can be entered using their name (if present in the same project) or leveraging their link id. The latter is mandatory if you're trying to deploy an ILB in a shared VPC environment.

module "ilb" {
  source     = "./modules/net-ilb-l7"
  name       = "ilb-test"
  project_id = var.project_id
  region     = "europe-west1"
  network    = "projects/my-host-project/global/networks/my-shared-vpc"
  subnetwork = "projects/my-host-project/regions/europe-west1/subnetworks/my-shared-subnet"

  backend_services_config = {
    my-backend-svc = {
      backends = [
        {
          group   = "projects/my-project/zones/europe-west1-a/instanceGroups/my-ig"
          options = null
        }
      ]
      health_checks = []
      log_config = null
      options = null
    }
  }
}
# tftest modules=1 resources=5

Defining Health Checks

If no health checks are specified, a default health check is created and associated to each backend service without health checks already associated. The default health check configuration can be modified through the health_checks_config_defaults variable.

If the health_checks_config_defaults variable is set to null, no default health checks will be automatically associted to backend services.

Alternatively, one or more health checks can be either contextually created or attached, if existing. If the id of the health checks specified is equal to one of the keys of the health_checks_config variable, the health check is contextually created; otherwise, the health check id is used as is, assuming an health check with that id alredy exists.

For example, to contextually create a health check and attach it to the backend service:

module "ilb" {
  source     = "./modules/net-ilb-l7"
  name       = "ilb-test"
  project_id = var.project_id
  region     = "europe-west1"
  network    = var.vpc.self_link
  subnetwork = var.subnet.self_link

  backend_services_config = {
    my-backend-svc = {
      backends = [
        {
          group   = "projects/my-project/zones/europe-west1-a/instanceGroups/my-ig"
          options = null
        }
      ],
      health_checks = ["hc-1"]
      log_config = null
      options = null
    }
  }

  health_checks_config = {
    hc-1 = {
      type    = "http"
      logging = true
      options = {
        timeout_sec = 5
      }
      check = {
        port_specification = "USE_SERVING_PORT"
      }
    }
  }
}
# tftest modules=1 resources=5

Network Endpoint Groups (NEGs)

Zonal Network Endpoint Groups (NEGs) can also be used, as shown in the example below.

module "ilb" {
  source     = "./modules/net-ilb-l7"
  name       = "ilb-test"
  project_id = var.project_id
  region     = "europe-west1"
  network    = var.vpc.self_link
  subnetwork = var.subnet.self_link

  backend_services_config = {
    my-backend-svc = {
      backends = [
        {
          group   = google_compute_network_endpoint_group.my-neg.id
          options = {
            balancing_mode               = "RATE"
            capacity_scaler              = 1.0
            max_connections              = null
            max_connections_per_instance = null
            max_connections_per_endpoint = null
            max_rate                     = 100
            max_rate_per_endpoint        = null
            max_rate_per_instance        = null
            max_utilization              = null
          }
        }
      ],
      health_checks = []
      log_config = null
      options = null
    }
  }
}

resource "google_compute_network_endpoint_group" "my-neg" {
  name         = "my-neg"
  project      = var.project_id
  network      = var.vpc.self_link
  subnetwork   = var.subnet.self_link
  default_port = "90"
  zone         = "europe-west1-b"
}
# tftest modules=1 resources=5

-->

Url-map

The url-map can be customized with lots of different configurations. This includes leveraging multiple backends in different parts of the configuration. Given its complexity, it's left to the user passing the right data structure.

For simplicity, if no configurations are given the first backend service defined (in alphabetical order, with priority to bucket backend services, if any) is used as the default_service, thus answering to the root (/) path.

Backend services can be specified as needed in the url-map configuration, referencing the id used to declare them in the backend services map. If a corresponding backend service is found, their object id is automatically used; otherwise, it is assumed that the string passed is the id of an already existing backend and it is given to the provider as it was passed.

In this example, we're using a backend service as the default backend

module "ilb" {
  source     = "./modules/net-ilb-l7"
  name       = "ilb-test"
  project_id = var.project_id
  region     = "europe-west1"
  network    = var.vpc.self_link
  subnetwork = var.subnet.self_link

  url_map_config = {
    default_service      = "my-backend-svc"
    default_url_redirect = null
    tests                = null
    host_rules           = []
    path_matchers = [
      {
        name = "my-example-page"
        path_rules = [
          {
            paths   = ["/my-example-page"]
            service = "another-group-backend"
          }
        ]
      }
    ]
  }

  backend_services_config = {
    my-backend-svc = {
      backends = [
        {
          group   = "projects/my-project/zones/europe-west1-a/instanceGroups/my-ig"
          options = null
        }
      ],
      health_checks = []
      log_config = null
      options = null
    },
    my-example-page = {
      backends = [
        {
          group   = "projects/my-project/zones/europe-west1-a/instanceGroups/another-ig"
          options = null
        }
      ],
      health_checks = []
      log_config = null
      options = null
    }
  }
}
# tftest modules=1 resources=6

Reserve a static IP address

Optionally, a static IP address can be reserved:

module "ilb" {
  source     = "./modules/net-ilb-l7"
  name       = "ilb-test"
  project_id = var.project_id
  region     = "europe-west1"
  network    = var.vpc.self_link
  subnetwork = var.subnet.self_link

  static_ip_config = {
    reserve = true
    options = null
  }

  backend_services_config = {
    my-backend-svc = {
      backends = [
        {
          group   = "projects/my-project/zones/europe-west1-a/instanceGroups/my-ig"
          options = null
        }
      ],
      health_checks = []
      log_config = null
      options = null
    }
  }
}
# tftest modules=1 resources=6

HTTPS And SSL Certificates

HTTPS is disabled by default but it can be optionally enabled.

When HTTPS is enabled, if the ids specified in the target_proxy_https_config variable are not found in the ssl_certificates_config map, they are used as is, assuming the ssl certificates already exist:

module "ilb" {
  source     = "./modules/net-ilb-l7"
  name       = "ilb-test"
  project_id = var.project_id
  region     = "europe-west1"
  network    = var.vpc.self_link
  subnetwork = var.subnet.self_link

  https = true

  target_proxy_https_config = {
    ssl_certificates = [
      "an-existing-cert"
    ]
  }

  backend_services_config = {
    my-backend-svc = {
      backends = [
        {
          group   = "projects/my-project/zones/europe-west1-a/instanceGroups/my-ig"
          options = null
        }
      ]
      health_checks = []
      log_config = null
      options = null
    }
  }
}
# tftest modules=1 resources=5

Otherwise, unmanaged certificates can also be contextually created:

module "ilb" {
  source     = "./modules/net-ilb-l7"
  name       = "ilb-test"
  project_id = var.project_id
  region     = "europe-west1"
  network    = var.vpc.self_link
  subnetwork = var.subnet.self_link

  https = true

  ssl_certificates_config = {
    my-domain = {
      domains = [
        "my-domain.com"
      ],
      tls_private_key      = tls_private_key.self_signed_key.private_key_pem
      tls_self_signed_cert = tls_self_signed_cert.self_signed_cert.cert_pem
    }
  }

  target_proxy_https_config = {
    ssl_certificates = [
      "my-domain"
    ]
  }

  backend_services_config = {
    my-backend-svc = {
      backends = [
        {
          group   = "projects/my-project/zones/europe-west1-a/instanceGroups/my-ig"
          options = null
        }
      ],
      health_checks = []
      log_config = null
      options = null
    }
  }
}

resource "tls_private_key" "self_signed_key" {
  algorithm = "RSA"
  rsa_bits  = 2048
}

resource "tls_self_signed_cert" "self_signed_cert" {
  private_key_pem       = tls_private_key.self_signed_key.private_key_pem
  validity_period_hours = 12
  early_renewal_hours   = 3
  dns_names             = ["example.com"]
  allowed_uses = [
    "key_encipherment",
    "digital_signature",
    "server_auth"
  ]
  subject {
    common_name  = "example.com"
    organization = "My Test Org"
  }
}
# tftest modules=1 resources=6

Components And Files Mapping

An Internal HTTP Load Balancer is made of multiple components, that change depending on the configurations. Sometimes, it may be tricky to understand what they are, and how they relate to each other. Following, we provide a very brief overview to become more familiar with them.

  • The global load balancer forwarding rule binds a frontend public Virtual IP (VIP) to an HTTP(S) target proxy.
  • If the target proxy is HTTPS, it requires one or more unmanaged SSL certificates.
  • Target proxies leverage url-maps: a set of L7 rules that create a mapping between specific hostnames, URIs (and more) to one or more backends services.
  • Backend services link to one or multiple infrastructure groups (GCE instance groups or NEGs). It is assumed in this module that groups have been previously created through other modules, and referenced in the input variables.
  • Backend services support one or more health checks, used to verify that the backend is indeed healthy, so that traffic can be forwarded to it. Health checks currently supported in this module are HTTP, HTTPS, HTTP2, SSL, TCP.

Files

name description resources
backend-services.tf Bucket and group backend services. google_compute_region_backend_service
forwarding-rule.tf IP Address and forwarding rule. google_compute_address · google_compute_forwarding_rule
health-checks.tf Health checks. google_compute_region_health_check
outputs.tf Module outputs.
ssl-certificates.tf SSL certificates. google_compute_region_ssl_certificate
target-proxy.tf HTTP and HTTPS target proxies. google_compute_region_target_http_proxy · google_compute_region_target_https_proxy
url-map.tf URL maps. google_compute_region_url_map
variables.tf Module variables.
versions.tf Version pins.

Variables

name description type required default
name Load balancer name. string
project_id Project id. string
region The region where to allocate the ILB resources. string
subnetwork The subnetwork where the ILB VIP is allocated. string
backend_services_config The backends services configuration. map(object({…})) {}
forwarding_rule_config Forwarding rule configurations. object({…}) {…}
health_checks_config Custom health checks configuration. map(object({…})) {}
health_checks_config_defaults Auto-created health check default configuration. object({…}) {…}
https Whether to enable HTTPS. bool false
network The network where the ILB is created. string "default"
ssl_certificates_config The SSL certificates configuration. map(object({…})) {}
static_ip_config Static IP address configuration. object({…}) {…}
target_proxy_https_config The HTTPS target proxy configuration. object({…}) null
url_map_config The url-map configuration. object({…}) null

Outputs

name description sensitive
backend_services Backend service resources.
forwarding_rule The forwarding rule.
health_checks Health-check resources.
ip_address The reserved IP address.
ssl_certificate_link_ids The SSL certificate.
target_proxy The target proxy.
url_map The url-map.