--- # ExternalDNS — publishes public DNS records for `public` services automatically (docs/09, R-DNS-02). # Watches Gateway/HTTPRoute (+Service); manages records in Cloudflare. Phase 0 STUB. apiVersion: helm.toolkit.fluxcd.io/v2 kind: HelmRelease metadata: name: external-dns namespace: external-dns spec: interval: 30m chart: spec: chart: external-dns version: ">=1.15.0 <1.16.0" # TODO(WS-NET): pin at bring-up; Renovate maintains sourceRef: kind: HelmRepository name: external-dns namespace: external-dns install: remediation: retries: 3 upgrade: remediation: retries: 3 values: provider: name: cloudflare # Watch Gateway API routes (Cilium Gateway) + Services. docs/09: records rendered from intent. sources: - gateway-httproute - service # domain-filter MUST be the actual Cloudflare ZONE (keithjackson.dev), not the platform subdomain # (home.keithjackson.dev) — ExternalDNS filters the account's zones by this value, and a subdomain # filter drops the parent zone → "no hosted zone matching record DNS Name" and nothing is created. # Scope stays effectively home.keithjackson.dev because that's the only suffix services request; # policy=sync + registry=txt only ever touch ExternalDNS-OWNED records, never the pre-existing # wildcard or other keithjackson.dev records. (docs/09; resolves the WS-NET TODO below.) domainFilters: - "${DNS_ZONE}" policy: sync # create + update + delete records as services come and go # Cloudflare API token: SOPS-encrypted secret, referenced BY NAME only (OQ-4, ADR-0007). env: - name: CF_API_TOKEN valueFrom: secretKeyRef: name: cloudflare-api-token key: api-token # R-DNS-02 PROVEN via the `service` source: the conformance/l2-behavioral/dns-exposure test # creates a LoadBalancer Service with an external-dns hostname and asserts the record auto-appears # in public DNS (then teardown + policy=sync removes it). gateway-httproute source wiring is the # same provider/zone path; a route-based test can follow when app routes exist.