Ctrl K
ComunidadGuías…

infra/lb.tf

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
locals {
  hosts = {
    api   = "api.${local.domain}"
    proxy = "proxy.${local.domain}"
    app   = "web.${local.domain}"
    docs  = "docs.${local.domain}"
    share = "share.${local.domain}"
    main  = local.domain
  }
}

resource "google_compute_global_address" "lb" {
  name       = "tamery-lb"
  ip_version = "IPV4"
}

resource "google_compute_region_network_endpoint_group" "this" {
  for_each = local.services

  name                  = "neg-${each.key}"
  region                = local.region
  network_endpoint_type = "SERVERLESS"

  cloud_run {
    service = google_cloud_run_v2_service.this[each.key].name
  }
}

resource "google_compute_backend_service" "this" {
  for_each = local.services

  name                  = "be-${each.key}"
  load_balancing_scheme = "EXTERNAL_MANAGED"
  protocol              = "HTTP"

  connection_draining_timeout_sec = 0

  backend {
    group = google_compute_region_network_endpoint_group.this[each.key].id
  }
}

resource "google_compute_url_map" "tamery" {
  name            = "tamery"
  default_service = google_compute_backend_service.this["main"].id

  dynamic "host_rule" {
    for_each = local.hosts
    content {
      hosts        = [host_rule.value]
      path_matcher = "pm-${host_rule.key}"
    }
  }

  dynamic "path_matcher" {
    for_each = local.hosts
    content {
      name            = "pm-${path_matcher.key}"
      default_service = google_compute_backend_service.this[path_matcher.key].id
    }
  }
}

resource "google_certificate_manager_dns_authorization" "tamery" {
  name   = "tamery-app"
  domain = local.domain
}

resource "google_certificate_manager_certificate" "tamery" {
  name = "tamery-app"

  managed {
    domains            = [local.domain, "*.${local.domain}"]
    dns_authorizations = [google_certificate_manager_dns_authorization.tamery.id]
  }
}

resource "google_certificate_manager_certificate_map" "tamery" {
  name = "tamery"
}

resource "google_certificate_manager_certificate_map_entry" "this" {
  for_each = {
    apex     = local.domain
    wildcard = "*.${local.domain}"
  }

  name         = each.key
  map          = google_certificate_manager_certificate_map.tamery.name
  hostname     = each.value
  certificates = [google_certificate_manager_certificate.tamery.id]
}

resource "google_certificate_manager_trust_config" "cloudflare" {
  name     = "cloudflare-origin-pull"
  location = "global"

  trust_stores {
    trust_anchors {
      pem_certificate = file("${path.module}/cloudflare-origin-pull-ca.pem")
    }
  }
}

# Cloudflare presents this CA's client certificate, so nothing else can reach the load balancer and forge cf-connecting-ip.
resource "google_network_security_server_tls_policy" "cloudflare_only" {
  name     = "cloudflare-only"
  location = "global"

  mtls_policy {
    client_validation_mode = "REJECT_INVALID"
    # The API stores the project number, and a project ID here replaces the policy on every plan.
    client_validation_trust_config = "projects/${data.google_project.current.number}/locations/global/trustConfigs/${google_certificate_manager_trust_config.cloudflare.name}"
  }

  depends_on = [google_project_service.this["networksecurity.googleapis.com"]]
}

resource "google_compute_target_https_proxy" "tamery" {
  name              = "tamery"
  url_map           = google_compute_url_map.tamery.id
  certificate_map   = "https://certificatemanager.googleapis.com/v1/${google_certificate_manager_certificate_map.tamery.id}"
  server_tls_policy = google_network_security_server_tls_policy.cloudflare_only.id
}

resource "google_compute_global_forwarding_rule" "https" {
  name                  = "tamery-https"
  load_balancing_scheme = "EXTERNAL_MANAGED"
  ip_address            = google_compute_global_address.lb.address
  target                = google_compute_target_https_proxy.tamery.id
  port_range            = "443"
}