feat(infra/dns): redirect-role domains 301 through a GCP LB (opt-in, provisions nothing by default) - #1198
Merged
Merged
Conversation
Lands the real content of #1196 (a WIP capture that got tangled with 45 commits of drift and would have deleted ~13k lines of unrelated, already-shipped work if merged/rebased directly -- hand-extracted just the 8 files that are this feature). #1196 stays open as the historical record; this supersedes it. - New web-redirect-gcp module: global HTTPS LB, managed cert, URL-map 301s, HTTP->HTTPS upgrade. No compute. GCP-specific by nature (an L7 redirect service); the redirect intent stays portable in domains.yaml, an AWS/other-cloud sibling would satisfy the same ip_address contract. - dns-records module: new redirect_ip input emits apex+www A records for role=redirect domains once a redirect service exists; new has_delegable_records output (app_records OR emitted redirect records) replaces has_app_records for the registrar fail-closed delegation check, so a redirect domain whose only record comes from the redirect IP isn't wrongly treated as empty. - domains.yaml: redirect_to on the 5 domains already marked role:redirect (socioslinux.org/sourceos.digital/.software/.systems -> sourceos.org, truthorbot.org -> truthorbot.net) -- consolidating domains already owned, not new claims. - enable_redirects defaults to false. Merging this provisions nothing -- no new GCP resources, no DNS changes, no cost. Flipping it on for real is a separate, deliberate follow-up. Verified: tofu validate clean on both the composed envs/dns config and the new module standalone; tofu fmt clean.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an opt-in “redirect plane” to the DNS Tofu environment, allowing role: redirect domains to 301 to a canonical target via a GCP global external HTTPS load balancer, while keeping the DNS record model cloud-neutral.
Changes:
- Introduces a new
web-redirect-gcpmodule that provisions a global external HTTP(S) LB with host-based 301 redirects and HTTP→HTTPS upgrade. - Extends the
dns-recordsmodule to optionally emit apex+wwwA records forrole=redirectdomains when a redirect service IP is provided, and exposeshas_delegable_recordsfor registrar fail-closed delegation gating. - Wires the redirect plane into
infra/tofu/envs/dnsbehindenable_redirects(defaultfalse) and annotates existing redirect-role domains withredirect_to.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| infra/tofu/modules/web-redirect-gcp/versions.tf | Declares required Tofu/provider versions for the redirect LB module. |
| infra/tofu/modules/web-redirect-gcp/variables.tf | Defines inputs for redirect host→target mapping, default target, and cert domains. |
| infra/tofu/modules/web-redirect-gcp/outputs.tf | Exposes the LB global IP for DNS A records. |
| infra/tofu/modules/web-redirect-gcp/main.tf | Implements the GCP global external HTTP(S) redirect LB configuration. |
| infra/tofu/modules/dns-records/variables.tf | Adds redirect_ip input used to emit redirect A records for redirect-role domains. |
| infra/tofu/modules/dns-records/main.tf | Emits apex+www A records when redirect_ip is set and computes has_delegable_records. |
| infra/tofu/modules/dns-records/outputs.tf | Exposes has_delegable_records for registrar delegation gating. |
| infra/tofu/envs/dns/variables.tf | Adds enable_redirects and default_redirect_target to control the redirect plane. |
| infra/tofu/envs/dns/main.tf | Wires web-redirect-gcp (counted/opt-in) and passes redirect IP into the record model; switches registrar gating to has_delegable_records. |
| infra/tofu/envs/dns/outputs.tf | Exposes redirect_ip output for visibility when redirects are enabled. |
| infra/tofu/envs/dns/domains.yaml | Adds redirect_to targets for existing role: redirect domains. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+41
to
+44
| content { | ||
| hosts = [host_rule.key] | ||
| path_matcher = local.matcher_name[host_rule.value] | ||
| } |
| variable "enable_redirects" { | ||
| type = bool | ||
| default = false | ||
| description = "When true (and dns_cloud=gcp), stand up the redirect LB and point redirect-role domains' apex/www A records at it. Off by default (creates a global IP + managed cert)." |
Copilot review on #1198: the DNS module emits both apex AND www A records at the redirect LB's IP for every redirect-role domain, but the URL map's host_rule only matched the apex host. A www visitor would hit this LB (DNS routes there) but match no host_rule, falling through to default_url_redirect -- the global default_target, socioprophet.com -- instead of that domain's actual redirect_to (e.g. www.sourceos.digital would have redirected to socioprophet.com instead of sourceos.org). Fixed: each host_rule now matches both the apex and www host. Verified in total isolation (throwaway local-only module, zero cloud/backend calls) that the for_each now produces {hosts: [apex, www], path_matcher} correctly per domain for all 5 real redirect domains in domains.yaml. Also tightened enable_redirects' description per the second review comment -- it undersold what actually gets provisioned (a full global external HTTP(S) LB: URL maps, target proxies, forwarding rules -- not just an IP and a cert).
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.
Suppressed comments (1)
infra/tofu/modules/web-redirect-gcp/main.tf:96
- Port 80 currently uses a separate URL map that only upgrades to HTTPS on the same host. That adds an extra redirect hop and (more importantly) makes HTTP traffic depend on the managed cert being provisioned on the LB before users can reach the final canonical target; during the cert provisioning window this can turn HTTP requests into TLS errors after the upgrade. Point the HTTP proxy at the same redirect URL map so HTTP requests can redirect directly to the canonical host without relying on the LB cert being active.
resource "google_compute_url_map" "http_to_https" {
name = "${var.name_prefix}-http-urlmap"
project = var.project
default_url_redirect {
https_redirect = true
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Supersedes #1196. That PR was a draft capture of interrupted work — its branch was 45+ commits behind main in a way that understated the real risk: diffing it against current main showed 273 files / 13,791 deletions, because it predates basically everything shipped since (Control-Plane phases, web-intel lane, WordOps Matrix, telemetry services, etc.). Merging or rebasing it directly would have been destructive. This PR hand-extracts the actual redirect feature — 8 files — cleanly onto current main instead.
What's here:
web-redirect-gcpmodule: a global HTTPS load balancer that 301-redirects hosts to a canonical target (global IP, managed cert, URL-map host rules, HTTP→HTTPS upgrade). No compute — pure LB config.dns-recordsmodule:redirect_ipinput emits apex+www A records forrole=redirectdomains once a redirect service exists; newhas_delegable_recordsoutput (app_records OR emitted redirect records) so a redirect domain whose only record comes from the redirect IP isn't wrongly treated as empty by the registrar's fail-closed delegation check.domains.yaml:redirect_toon the 5 domains already markedrole: redirect—socioslinux.org/sourceos.digital/.software/.systems→sourceos.org,truthorbot.org→truthorbot.net. These are domains already owned in the registry, being consolidated — not new claims.Provisions nothing on merge.
enable_redirectsdefaults tofalse. Merging this ships the capability wired and dormant — no new GCP resources, no DNS changes, no cost. Flipping it on (enable_redirects = true, then a realtofu apply) is a separate, deliberate step I'd want its own explicit go-ahead for, given it provisions real billable infra and repoints live DNS (the managed cert also only provisions after the A records point at the new LB — expect a ~15–60min gap, per the module's own note).Verified:
tofu validateclean on the composedenvs/dnsconfig (with the new module actually wired in, not just standalone) and onweb-redirect-gcpin isolation.tofu fmt -checkclean on every touched file.I'll leave #1196 open as the historical record of the original capture rather than closing it silently.