Skip to content

feat(cluster): CNAMEs + Access app for headlamp & k3s API#6

Merged
xnoto merged 1 commit intomainfrom
feat/cluster-access-apps
Apr 30, 2026
Merged

feat(cluster): CNAMEs + Access app for headlamp & k3s API#6
xnoto merged 1 commit intomainfrom
feat/cluster-access-apps

Conversation

@xnoto
Copy link
Copy Markdown
Contributor

@xnoto xnoto commented Apr 30, 2026

Summary

Sets up the DNS + auth foundation for the upcoming Headlamp dashboard and kubectl-via-tunnel access:

  • `cf-tunnels.tf` — extend `cluster_apps_hostnames` with `headlamp` and `k3s` so the existing for_each creates CNAMEs into the cluster-apps tunnel. Drop `ansible` since AWX is being deprecated.
  • `cf-access-k3s.tf` (new) — Cloudflare Access self_hosted app for `k3s.makeitwork.cloud`. `cloudflared access tcp` clients run the Access OIDC flow against this before the TCP tunnel opens. Allowed via the existing GitHub IdP, restricted to the existing makeitworkcloud-admins group.

Headlamp deliberately does not get its own Access app — it'll auth via ArgoCD's embedded Dex (added in the next PR as a static client). Same pattern grafana uses for its built-in OAuth.

Test plan

  • After apply: `tofu plan` clean
  • After apply: `dig k3s.makeitwork.cloud` resolves to Cloudflare proxy IPs
  • After apply: Cloudflare dashboard shows the new "k3s API" Access app
  • Smoke after the matching kustomize-cluster TunnelBinding lands: `cloudflared access tcp --hostname k3s.makeitwork.cloud --url localhost:6443` opens after GitHub OAuth, then `kubectl --server=https://localhost:6443\` reaches the apiserver

🤖 Generated with Claude Code

- cf-tunnels.tf: add `headlamp` and `k3s` to cluster_apps_hostnames so
  CNAMEs resolve through the cluster-apps tunnel. Drop `ansible` (AWX
  is being deprecated).
- cf-access-k3s.tf (new): Cloudflare Access self_hosted application
  protecting k3s.makeitwork.cloud. Pairs with the upcoming TunnelBinding
  in kustomize-cluster that fronts kube-apiserver as a TCP tunnel.
  Admins-only via the existing GitHub IdP and access group.

Headlamp doesn't get its own Access app — it'll authenticate via
ArgoCD's embedded Dex (separate PR adds the static client).
@github-actions
Copy link
Copy Markdown

OpenTofu Plan

OpenTofu will perform the following actions:

  # cloudflare_dns_record.cluster_apps["ansible"] will be destroyed
  # (because key ["ansible"] is not in for_each map)
  - resource "cloudflare_dns_record" "cluster_apps" {
      - content     = "7a3b548e-734f-427c-bd37-b360199f5433.cfargotunnel.com" -> null
      - created_on  = "2026-04-30T01:53:39Z" -> null
      - id          = "45fbbfd0a37a02a4ceb01ad39e8c9263" -> null
      - meta        = jsonencode({})
      - modified_on = "2026-04-30T01:53:39Z" -> null
      - name        = "ansible.makeitwork.cloud" -> null
      - proxiable   = true -> null
      - proxied     = true -> null
      - settings    = {
          - flatten_cname = false -> null
          - ipv4_only     = false -> null
          - ipv6_only     = false -> null
        } -> null
      - tags        = [] -> null
      - ttl         = 1 -> null
      - type        = "CNAME" -> null
      - zone_id     = (sensitive value) -> null
    }

  # cloudflare_dns_record.cluster_apps["headlamp"] will be created
  + resource "cloudflare_dns_record" "cluster_apps" {
      + content          = "7a3b548e-734f-427c-bd37-b360199f5433.cfargotunnel.com"
      + created_on       = (known after apply)
      + id               = (known after apply)
      + meta             = (known after apply)
      + modified_on      = (known after apply)
      + name             = "headlamp"
      + proxiable        = (known after apply)
      + proxied          = true
      + settings         = (known after apply)
      + tags             = (known after apply)
      + tags_modified_on = (known after apply)
      + ttl              = 1
      + type             = "CNAME"
      + zone_id          = (sensitive value)
    }

  # cloudflare_dns_record.cluster_apps["k3s"] will be created
  + resource "cloudflare_dns_record" "cluster_apps" {
      + content          = "7a3b548e-734f-427c-bd37-b360199f5433.cfargotunnel.com"
      + created_on       = (known after apply)
      + id               = (known after apply)
      + meta             = (known after apply)
      + modified_on      = (known after apply)
      + name             = "k3s"
      + proxiable        = (known after apply)
      + proxied          = true
      + settings         = (known after apply)
      + tags             = (known after apply)
      + tags_modified_on = (known after apply)
      + ttl              = 1
      + type             = "CNAME"
      + zone_id          = (sensitive value)
    }

  # cloudflare_zero_trust_access_application.k3s will be created
  + resource "cloudflare_zero_trust_access_application" "k3s" {
      + account_id                 = (sensitive value)
      + allowed_idps               = [
          + "e584ea47-1251-4939-95f4-4daf4a58cd31",
        ]
      + app_launcher_visible       = true
      + aud                        = (known after apply)
      + destinations               = (known after apply)
      + domain                     = "k3s.makeitwork.cloud"
      + http_only_cookie_attribute = true
      + id                         = (known after apply)
      + name                       = "k3s API"
      + policies                   = [
          + {
              + decision   = "allow"
              + include    = [
                  + {
                      + group = {
                          + id = "e0d9e873-31d7-4536-9234-3dad8a99d84d"
                        }
                    },
                ]
              + name       = "makeitworkcloud-admins"
              + precedence = 1
            },
        ]
      + self_hosted_domains        = (known after apply)
      + session_duration           = "24h"
      + type                       = "self_hosted"
    }

Plan: 3 to add, 0 to change, 1 to destroy.

@xnoto xnoto merged commit 9c27f39 into main Apr 30, 2026
3 checks passed
@xnoto xnoto deleted the feat/cluster-access-apps branch April 30, 2026 02:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant