Skip to content

Load Balancer

A HTTP(S) Load Balancer in GCP is pretty straightforward to configure from the user interface. It is however made up of many components, which need to be configured separately now that we are calling the cloud API through Terraform.

Global Forwarding Rule -> URL Map & HTTP Proxy -> Backend & Healthcheck -> Instance Group -> Instance

In this section, we will create a complete LB configuration that contains all the necessary resources, to allow access to our Compute Engine instance(s). r. You will learn how to create a bit more complex setup of multiple resources and making changes to existing things in the code.

Exercises: Instance Group

  1. Start by modifying the source_ranges to [] for the allow-http rule
    • This will stop direct access to the instance, but we will sort that out with the Load Balancer
    • You can now run terraform plan to see what would happen
  2. Create a resource block with type google_compute_instance_group named default with following parameters:
    • name = ${var.name}-vm-group"
    • description = "Web servers instance group"
    • zone = var.zone
    • instances = [google_compute_instance.default.self_link]
    • Remember the project again, unless you moved it to the provider configuration
    • named_port port should match the 80 used for HTTP
Help

terraform/loadbalancer.tf

resource "google_compute_instance_group" "default" {
    name        = "${var.name}-vm-group"
    description = "Web servers instance group"
    zone        = var.zone
    project     = var.project

    instances = [
        google_compute_instance.default.self_link
    ]

    named_port {
        name = "http"
        port = "80"
    }
}

Extra

  1. Create multiple instances of google_compute_instance with for_each and reference all of them in instance
    • for_each is similar to count, but takes a map or a set
    • Hint: for_each = toset(["1", "2")]
      • Then reference the number in the instance's name, with ${each.key}

Exercises: Healthcheck & Backend

  1. Create a resource block with type google_compute_health_check named healthcheck with following parameters:
    • name = "${var.name}-healthcheck"
    • timeout_sec = 1
    • check_interval_sec = 1
    • http_health_check block's port to match 80
    • Remember the project again, unless you moved it to the provider configuration
  2. Create a resource block with type google_compute_backend_service named backend_service with following parameters
    • name = "${var.name}-backend-service"
    • port_name = "http"
    • protocol= "HTTP"
    • health_checks = [google_compute_health_check.healthcheck.self_link]
    • Remember the project again, unless you moved it to the provider configuration
Help

terraform/loadbalancer.tf

resource "google_compute_health_check" "healthcheck" {
    name               = "${var.name}-healthcheck"
    project            = var.project
    timeout_sec        = 1
    check_interval_sec = 1

    http_health_check {
        port = 80
    }
}

resource "google_compute_backend_service" "backend_service" {
    name          = "${var.name}-backend-service"
    project       = var.project

    port_name     = "http"
    protocol      = "HTTP"
    health_checks = [google_compute_health_check.healthcheck.self_link]

    backend {
        group                 = google_compute_instance_group.default.self_link
        balancing_mode        = "RATE"
        max_rate_per_instance = 100
    }
}

Exercises: URL Map & HTTP Proxy

  1. Create a resource block with type google_compute_url_map named url_map with following parameters
    • name = "${var.name}-load-balancer"
    • default_service = google_compute_backend_service.backend_service.self_link
    • Remember the project again, unless you moved it to the provider configuration
  2. Create a resource block with type google_compute_target_http_proxy named target_http_proxy with following parameters
    • name = "${var.name}-proxy"
    • url_map = google_compute_url_map.url_map.self_link
    • Remember the project again, unless you moved it to the provider configuration
Help

terraform/loadbalancer.tf

resource "google_compute_url_map" "url_map" {
    name            = "${var.name}-load-balancer"
    project     = var.project
    default_service = google_compute_backend_service.backend_service.self_link
}

resource "google_compute_target_http_proxy" "target_http_proxy" {
    name    = "${var.name}-proxy"
    project     = var.project
    url_map = google_compute_url_map.url_map.self_link
}

Exercises: Global Forwarding Rule

  1. Create a resource block with type google_compute_global_forwarding_rule named global_forwarding_rule with following parameters
    • name = "${var.name}-proxy"
    • target = google_compute_target_http_proxy.target_http_proxy.self_link
    • port_range= "80"
    • Remember the project again, unless you moved it to the provider configuration
  2. Create a output block named load-balancer-ip-address with the following parameters
    • value = google_compute_global_forwarding_rule.global_forwarding_rule.ip_address
Help

terraform/loadbalancer.tf

resource "google_compute_global_forwarding_rule" "global_forwarding_rule" {
    name       = "${var.name}-global-forwarding-rule"
    project     = var.project

    target     = google_compute_target_http_proxy.target_http_proxy.self_link
    port_range = "80"
}

Check your configuration

To check your Terraform configuration run:

terraform plan

What changed? Does everything look OK?

Apply your configuration

Run terraform apply, to make changes to the infrastructure:

terraform apply

After the apply, you will see the LB IP address as an output. Try to access that with a browser, does it work the same way as when diretly accessing the VM?


Answer

terraform/loadbalancer.tf

resource "google_compute_instance_group" "default" {
    name        = "${var.name}-vm-group"
    description = "Web servers instance group"
    zone        = var.zone
    project     = var.project

    instances = [
        google_compute_instance.default.self_link
    ]

    named_port {
        name = "http"
        port = "80"
    }
}

resource "google_compute_health_check" "healthcheck" {
    name               = "${var.name}-healthcheck"
    project            = var.project
    timeout_sec        = 1
    check_interval_sec = 1

    http_health_check {
        port = 80
    }
}

resource "google_compute_backend_service" "backend_service" {
    name          = "${var.name}-backend-service"
    project       = var.project

    port_name     = "http"
    protocol      = "HTTP"
    health_checks = [google_compute_health_check.healthcheck.self_link]

    backend {
        group                 = google_compute_instance_group.default.self_link
        balancing_mode        = "RATE"
        max_rate_per_instance = 100
    }
}

resource "google_compute_url_map" "url_map" {
    name            = "${var.name}-load-balancer"
    project     = var.project
    default_service = google_compute_backend_service.backend_service.self_link
}

resource "google_compute_target_http_proxy" "target_http_proxy" {
    name    = "${var.name}-proxy"
    project     = var.project
    url_map = google_compute_url_map.url_map.self_link
}

resource "google_compute_global_forwarding_rule" "global_forwarding_rule" {
    name       = "${var.name}-global-forwarding-rule"
    project     = var.project

    target     = google_compute_target_http_proxy.target_http_proxy.self_link
    port_range = "80"
}

Next

That's it! You have completed all the exercises. All that is left is to tear it all down.