From 2e09aab5bb27037b8081f6098b9998e05fc05d5c Mon Sep 17 00:00:00 2001 From: xnoto Date: Fri, 28 Aug 2026 14:54:00 -0600 Subject: [PATCH] feat: preserve cluster tunnel lifecycle --- AGENTS.md | 2 +- README.md | 2 +- cf-tunnels.tf | 23 +++++++++++++++-------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 2c0886a..2212886 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,6 +2,6 @@ OpenTofu root for Make IT Work Cloud Cloudflare infrastructure. -This root owns bootstrap and non-tunnel Cloudflare resources. `kustomize-cluster` owns workload TunnelBinding routes, workload CNAMEs, and ownership TXT records. For tunnel DNS conflicts, identify the current owner; do not import or recreate an operator-owned record here. +This root owns the durable `cluster-apps-k3s` tunnel identity, bootstrap DNS, and non-tunnel Cloudflare resources. `kustomize-cluster` references that tunnel with `existingTunnel` and owns local ingress configuration, workload CNAMEs, and ownership TXT records through `TunnelBinding`. Do not manage local cloudflared configuration or workload DNS here. Use GitHub MCP and PR CI plans as validation authority. `main` is an environment-gated apply path; use scoped branches and PRs, never direct pushes. Shared workflow and runner ownership belongs to `shared-workflows` and `images/tfroot-runner`. Never expose API tokens, tunnel credentials, state, decrypted SOPS data, or sensitive plans. diff --git a/README.md b/README.md index 0e30e32..48d9a84 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ No modules. | [cloudflare_zero_trust_access_identity_provider.github](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_identity_provider) | resource | | [cloudflare_zero_trust_access_service_token.mcp_gateway](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_service_token) | resource | | [cloudflare_zero_trust_organization.main](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_organization) | resource | +| [cloudflare_zero_trust_tunnel_cloudflared.cluster_apps](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_cloudflared) | resource | | [cloudflare_zero_trust_tunnel_cloudflared.warp](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_cloudflared) | resource | | [cloudflare_zero_trust_tunnel_cloudflared_route.private_network](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_cloudflared_route) | resource | | [cloudflare_zone.xnoto_dev](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zone) | resource | @@ -53,7 +54,6 @@ 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 83d3020..1fbd8e8 100644 --- a/cf-tunnels.tf +++ b/cf-tunnels.tf @@ -1,14 +1,21 @@ -# The cluster-apps tunnel is created by cloudflare-operator. This root owns the -# two bootstrap DNS records that provide access to the Kubernetes API before -# cluster workloads can reconcile. Workload tunnel DNS is managed by the -# corresponding TunnelBinding in kustomize-cluster. -data "cloudflare_zero_trust_tunnel_cloudflared" "cluster_apps" { +# The cluster-apps tunnel has a durable lifecycle outside Kubernetes so a +# replacement cluster can reconnect to the same tunnel ID. cloudflare-operator +# owns its local ingress configuration and workload DNS through TunnelBindings. +resource "cloudflare_zero_trust_tunnel_cloudflared" "cluster_apps" { account_id = local.account_id - filter = { - name = "cluster-apps-k3s" + name = "cluster-apps-k3s" + config_src = "local" + + lifecycle { + prevent_destroy = true } } +import { + to = cloudflare_zero_trust_tunnel_cloudflared.cluster_apps + id = "03f750691b4ad4d59aa4b7205adaa108/d17bee03-8687-46a7-831b-df48aacdea1e" +} + locals { cluster_bootstrap_hostnames = ["api", "k3s"] } @@ -18,7 +25,7 @@ resource "cloudflare_dns_record" "cluster_bootstrap" { zone_id = local.zone_id type = "CNAME" name = each.value - content = "${data.cloudflare_zero_trust_tunnel_cloudflared.cluster_apps.id}.cfargotunnel.com" + content = "${cloudflare_zero_trust_tunnel_cloudflared.cluster_apps.id}.cfargotunnel.com" proxied = true ttl = 1 }