Terraform Gcp Https Load Balancer Google_Compute_Url_Map with Variable Length of Host_Rule Blocks

I'm a Terraform novice creating GCP external HTTP/HTTPS load balancers that route different hostnames to different backends. In a working proof of concept, I have two hostnames supported, like this:

locals {
  hostnames = [ "", "" ]
}

resource "google_compute_url_map" "MY_URL_MAP_HTTPS" {
  name               = "mylb-https"
  description        = "External HTTPS load balancer for multiple hostnames"
  host_rule {
    hosts            = [ local.hostnames[0] ]
    path_matcher     = "site1-path-matcher"
  }
  host_rule {
    hosts            = [ local.hostnames[1] ]
    path_matcher     = "site2-path-matcher"
  }
  path_matcher {
    name             = "site1-path-matcher"
    default_service  = "projects/myproject/global/backendServices/site1-backend-service"
  }
  path_matcher {
    name             = "site2-path-matcher"
    default_service  = "projects/myproject/global/backendServices/site2-backend-service"
  }
}

I know I can do a for loop when Terraform expects a list, such as associating multiple SSL certificates with a target proxy:

resource "google_compute_ssl_certificate" "MY_SSL_CERT" {
  count          = length(local.hostnames)
  name           = replace(local.hostnames[count.index], ".", "-")
}
resource "google_compute_target_https_proxy" "MY_TARGET_PROXY_HTTPS" {
  ssl_certificates      = [ 
    for cert in google_compute_ssl_certificate.MY_SSL_CERT
      cert.id
  ]
}

But how can a do a for loop on the host_rule and path_matcher blocks? Is this possible?

1 Answer

Found a bug report which helped me see dynamic blocks are the solution:

variable "hostnames" {
  type                 = list(string)
  default              = null
}

resource "google_compute_url_map" "URL_MAP_HTTPS" {
  name                  = "urlmap-https"
  default_service       = google_compute_backend_bucket.default.id
  dynamic "host_rule" {
    for_each = var.hostnames
    content {
      hosts               = [ host_rule.value]
      path_matcher        = "path-matcher-${host_rule.key}"
    }
  }
  dynamic "path_matcher" {
    for_each = var.hostnames
    content {
      name                = "path-matcher-${path_matcher.key}"
      default_service     = google_compute_backend_service.default[path_matcher.key].id
    }
  }
}

This is also the solution to having a variable number of backend blocks to use with google_compute_backend_service and google_compute_region_backend_service.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Sarah Jenkins

Sarah Jenkins

Senior Technology Editor & AI Specialist

Sarah Jenkins is a veteran tech journalist with over 12 years of experience covering artificial intelligence, mobile innovations, and digital ethics. Her insights have appeared in leading technology publications worldwide.

Share this article
Twitter Facebook Pinterest