From 19911eb90333d5f7fa2bd9756c91958db7513d3f Mon Sep 17 00:00:00 2001 From: xnoto Date: Wed, 29 Apr 2026 19:50:33 -0600 Subject: [PATCH] feat(cluster-apps): manage tunnel-fronted CNAMEs for argocd/grafana/status/ansible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cloudflare-operator creates the cluster-apps tunnel but does not manage DNS records — it only configures the cloudflared deployment to route hostnames it sees in TunnelBindings. Without CNAMEs pointing each FQDN at .cfargotunnel.com, requests reach Cloudflare's edge but error out with 530/1033. Look up the operator-owned tunnel by name and write a CNAME for each fronted hostname. Tunnel ID gets refreshed automatically if the operator ever recreates the tunnel. --- README.md | 2 ++ cf-tunnels.tf | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9940de0..4c6934c 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ No modules. | [cloudflare_dns_record.api](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource | | [cloudflare_dns_record.apps](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource | | [cloudflare_dns_record.apps_wildcard](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource | +| [cloudflare_dns_record.cluster_apps](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource | | [cloudflare_dns_record.mx_primary](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource | | [cloudflare_dns_record.mx_secondary](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource | | [cloudflare_dns_record.onion](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource | @@ -49,6 +50,7 @@ No modules. | [cloudflare_zone_setting.minify](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zone_setting) | resource | | [cloudflare_zone_setting.polish](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zone_setting) | resource | | [cloudflare_zone_setting.rocket_loader](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zone_setting) | resource | +| [cloudflare_zero_trust_tunnel_cloudflared.cluster_apps](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/data-sources/zero_trust_tunnel_cloudflared) | data source | | [cloudflare_zone.makeitwork_cloud](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/data-sources/zone) | data source | | [sops_file.secret_vars](https://registry.terraform.io/providers/carlpett/sops/latest/docs/data-sources/file) | data source | diff --git a/cf-tunnels.tf b/cf-tunnels.tf index af41a9a..a0ff90e 100644 --- a/cf-tunnels.tf +++ b/cf-tunnels.tf @@ -2,8 +2,39 @@ # # The cluster-apps tunnel is created and owned by cloudflare-operator # (see kustomize-cluster/operators/cloudflare/cluster-tunnel.yaml). Tunnel -# credentials live in the cluster's Secret. DNS records for app endpoints -# are reconciled by TunnelBinding resources, not managed here. +# credentials live in the cluster's Secret. CNAME records for the apps +# fronted by that tunnel are managed below. + +# Look up the cluster-apps tunnel by name so DNS records can target it +# without hard-coding a UUID that changes if the operator recreates it. +data "cloudflare_zero_trust_tunnel_cloudflared" "cluster_apps" { + account_id = local.account_id + filter = { + name = "cluster-apps-k3s" + } +} + +# Hostnames fronted by the cluster-apps tunnel. The TunnelBinding in +# kustomize-cluster picks up traffic for each FQDN; this CNAME just tells +# Cloudflare's edge which tunnel to route requests through. +locals { + cluster_apps_hostnames = [ + "argocd", + "grafana", + "status", + "ansible", + ] +} + +resource "cloudflare_dns_record" "cluster_apps" { + for_each = toset(local.cluster_apps_hostnames) + zone_id = local.zone_id + type = "CNAME" + name = each.value + content = "${data.cloudflare_zero_trust_tunnel_cloudflared.cluster_apps.id}.cfargotunnel.com" + proxied = true + ttl = 1 +} resource "cloudflare_zero_trust_tunnel_cloudflared" "warp" { account_id = local.account_id