GCP Cloud Run domain mapping no longer working with Google Search Console switch

451 Views Asked by At

We've been regularly using Cloud Run with custom domain mappings, mapping to a proxied URL from Cloudflare. The mappings and DNS records are managed in Terraform.

As of the last week or so, the domain mapping handshake from Cloudflare to GCP no longer completes. It used to take 1-2 hours, now it never finishes.

We've made no changes to our flow, and nothing has changed on the Cloudflare side. However one thing that has happened is the deprecation of Google Webmaster Tools UI (which we used to use to verify domains) for Google Search Console. We had to re-add our domains to that UI and re-add the SAs as owners.

The switch to Search Console leads me to believe something has not carried forward correctly under the hood of Cloud Run's domain mapping, since that is the only thing that has changed.

2

There are 2 best solutions below

1
Kevin Campbell On BEST ANSWER

We have this same issue. It doesn't seem to be down to the webmaster UI tool changes though. If we disable Cloudflare proxying on the hostname then the mappings are created successfully. It seems that Cloudflare is interfering with the ACME HTTP-01 challenge from Google.

Update: We've tracked down the issue on Cloudflare. Cloudflare was blocking the /.well-known/acme-challenge/ requests with a Captcha. You can see this under Security > Events

enter image description here

We resolved the problem by adding a page rule which prevents Cloudflare from doing a browser identity check on the /.well-known/acme-challenge/* urls

enter image description here

0
Andre Miras On

Based on Kevin's answer and pointers gave in the community forum here's the Terraform setup I'm using. Note that I disabled HTTPS rewrites and lowered security level as it gave me more consistent results. I shared the entire setup to give more context, but the resource we're really interested in is cloudflare_page_rule.acme_challenge_bypass.

## Variables

variable "domain_suffix" {
  type        = string
  description = "The domain suffix used by all subdomains."
  default     = "example.com"
}

variable "domain_prefix" {
  type        = string
  description = "The subdomain prefix."
  default     = "sub"
}

variable "cloud_run_location" {
  type        = string
  description = "The location of the Cloud Run services."
  default     = "us-central1"
}

locals {
  full_domain = "${domain_prefix}.${domain_suffix}"
}


## Cloudflare resources

resource "cloudflare_record" "subdomain" {
  zone_id = var.cloudflare_zone_id
  name    = var.domain_prefix
  value   = "ghs.googlehosted.com"
  type    = "CNAME"
  proxied = true
}

# Disable security and browser integrity checks for the ACME challenge as GCP needs it for custom domain mapping
resource "cloudflare_page_rule" "acme_challenge_bypass" {
  zone_id = var.cloudflare_zone_id
  target  = "${local.full_domain}/.well-known/acme-challenge/*"
  actions {
    automatic_https_rewrites = "off"
    browser_check            = "off"
    cache_level              = "bypass"
    security_level           = "essentially_off"
  }
}


## Cloud Run resources

resource "google_cloud_run_v2_service" "default" {
  name     = "cloudrun-service"
  location = var.cloud_run_location
  template {
    containers {
      image = "us-docker.pkg.dev/cloudrun/container/hello"
    }
  }
}

resource "google_cloud_run_domain_mapping" "default" {
  location = var.cloud_run_location
  name     = local.full_domain
  metadata {
    namespace = var.project
  }
  spec {
    route_name = google_cloud_run_v2_service.default.name
  }
}

I always got domain verified under 20 minutes on that setup.