Skip to content

feat(coredns): migrate docker-provider CoreDNS from Deployment to HelmRelease#62

Merged
devantler merged 2 commits into
mainfrom
claude/coredns-helmrelease
Jul 9, 2026
Merged

feat(coredns): migrate docker-provider CoreDNS from Deployment to HelmRelease#62
devantler merged 2 commits into
mainfrom
claude/coredns-helmrelease

Conversation

@devantler

Copy link
Copy Markdown
Contributor

🤖 Generated by the Daily AI Assistant

Why

CoreDNS was the only infrastructure controller still hand-rolled as a Deployment + ConfigMap instead of the repo's standard Flux HelmRelease pattern every other controller uses (remediation, PDB, topology conventions). That's a consistency/maintenance gap, and it means CoreDNS doesn't inherit the standard upgrade path.

What

Migrates the docker provider only to the upstream coredns/coredns HelmRelease, reproducing the current Deployment's behavior exactly (same image, resources, Corefile, tolerations). Two couplings needed handling: the chart always renders its own Service+ConfigMap (so the shared base ConfigMap is dropped for docker only), and Talos's own bootstrapped CoreDNS is disabled via a new machine-config patch so it doesn't fight the Helm-owned one. The hetzner provider is untouched.

Validated offline via ksail workload validate + kubectl kustomize (both clean). The actual DNS handoff (ClusterIP takeover from Talos) needs a real cluster to confirm — that happens in this repo's own CI, which is the promotion gate here, not something provable statically.

Fixes #14

…mRelease

CoreDNS was the only infrastructure controller still shipped as a
hand-rolled Deployment + Corefile ConfigMap instead of the repo's
standard Flux HelmRelease pattern (remediation/PDB/topology
conventions every other controller uses). Docker-provider only —
hetzner keeps Talos-managed CoreDNS + its existing Corefile patch.

Two couplings made a naive swap unsafe (see issue #14 investigation):
1. The upstream coredns/coredns chart always renders a Service +
   ConfigMap alongside the Deployment (no way to render "Deployment
   only"), so the HelmRelease owns the whole stack for docker; the
   shared base ConfigMap is dropped from the docker kustomization
   (bases/ stays hetzner-only).
2. Talos reconciles its own bootstrapped CoreDNS, so
   cluster.coreDNS.disabled: true is added to the Talos machine
   config (talos-local/cluster/disable-coredns.yaml) to stop it
   fighting the Helm-owned Deployment.

Values reproduce the current Deployment 1:1: replicas, resources,
securityContext (chart default), anti-affinity, tolerations,
priorityClassName, the exact Corefile via the chart's servers[]
schema, serviceAccount.create:false (Talos already bootstraps the
coredns ServiceAccount+RBAC independently of its own CoreDNS
Deployment) + rbac.create:false, service.clusterIP pinned to Talos's
default kube-dns address (10.96.0.10) and service.name: kube-dns so
DNS resolution isn't interrupted.

Validated offline: `ksail --config ksail.yaml workload validate`
renders the HelmRelease and passes (the one unrelated failure
elsewhere in the tree — testkube OCI chart fetch — reproduces
identically on unmodified main). `kubectl kustomize` on the overlay
and the hetzner sibling (untouched) both build clean. The actual DNS
behavior (ClusterIP takeover, Talos CoreDNS handoff) needs the repo's
own CI, which brings up a real Talos+Docker cluster — that's the
promotion gate, not something this draft can prove statically.

Fixes #14
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The Docker provider CoreDNS manifests were switched to Flux-managed Helm resources, with a new HelmRepository and HelmRelease added for the CoreDNS chart. The Kustomize resources list now points to the Helm manifests, and the Talos local cluster configuration now disables built-in CoreDNS.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR replaces the docker CoreDNS Deployment with a HelmRelease while preserving the runtime configuration called for in #14.
Out of Scope Changes check ✅ Passed The additional Helm repository and Talos disable patch are in scope for the CoreDNS migration and do not appear unrelated.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title clearly states the main change: migrating docker-provider CoreDNS from a Deployment to a HelmRelease.
Description check ✅ Passed The description matches the PR’s scope and explains the CoreDNS HelmRelease migration and Talos disablement.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@k8s/providers/docker/infrastructure/controllers/coredns/helm-release.yaml`:
- Around line 21-27: The CoreDNS HelmRelease remediation settings in the Helm
release manifest currently use infinite retries for both install and upgrade.
Update the remediation configuration in the HelmRelease resource so failures do
not retry forever, or otherwise add a bounded retry/backoff strategy that allows
the release to surface a terminal failure state; use the existing install and
upgrade remediation blocks to make the change.
- Around line 1-9: The CoreDNS HelmRelease currently assumes Talos provides the
coredns identity, but with cluster.coreDNS.disabled set to true that no longer
exists, so the chart must own it. Update the HelmRelease so CoreDNS creates or
receives its ServiceAccount and RBAC by enabling serviceAccount.create and
rbac.create, or otherwise define the coredns ServiceAccount, ClusterRole, and
ClusterRoleBinding separately. Use the HelmRelease values block and the CoreDNS
release configuration as the place to make this change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 490de46f-fe2f-42bf-8a14-6d7376b448ee

📥 Commits

Reviewing files that changed from the base of the PR and between 35af9f6 and 7fc21eb.

📒 Files selected for processing (6)
  • k8s/providers/docker/infrastructure/controllers/coredns/deployment.yaml
  • k8s/providers/docker/infrastructure/controllers/coredns/helm-release.yaml
  • k8s/providers/docker/infrastructure/controllers/coredns/helm-repository.yaml
  • k8s/providers/docker/infrastructure/controllers/coredns/kustomization.yaml
  • k8s/providers/docker/infrastructure/controllers/coredns/pod-disruption-budget.yaml
  • talos-local/cluster/disable-coredns.yaml
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • devantler-tech/actions (auto-detected)
  • devantler-tech/reusable-workflows (auto-detected)
💤 Files with no reviewable changes (2)
  • k8s/providers/docker/infrastructure/controllers/coredns/deployment.yaml
  • k8s/providers/docker/infrastructure/controllers/coredns/pod-disruption-budget.yaml
📜 Review details
⚠️ CI failures not shown inline (2)

GitHub Actions: 🧱 Validate Scaffold / Validate Scaffold: feat(coredns): migrate docker-provider CoreDNS from Deployment to HelmRelease

Conclusion: failure

View job details

##[group]Run ksail --config ksail.yaml workload validate
 �[36;1mksail --config ksail.yaml workload validate�[0m
 shell: /usr/bin/bash -e {0}
 ##[endgroup]
 ✅ Validating kustomizations...
 ✔ bases/bootstrap validated
 ✔ bases/bootstrap/priority-classes validated
 ✔ bases/apps/homepage validated
 ✔ bases/infrastructure/alerts validated
 ✔ bases/infrastructure/certificates validated
 ✔ bases/infrastructure/cluster-policies validated
 ✔ bases/infrastructure/cluster-role-bindings validated
 ✔ bases/infrastructure/cluster-roles validated
 ✔ bases/apps/whoami validated
 ✔ bases/apps/headlamp validated
 ✔ bases/apps validated
 ✔ bases/infrastructure/controllers/alloy validated
 ✔ bases/infrastructure/cluster-secret-stores validated
 ✔ bases/infrastructure/controllers/auth-proxy validated
 ✔ bases/infrastructure/controllers/cert-manager validated
 ✔ bases/infrastructure/controllers/cilium validated
 ✔ bases/infrastructure/controllers/coredns validated
 ✔ bases/infrastructure/controllers/cloudnative-pg validated
 ✔ bases/infrastructure/controllers/external-secrets validated
 ✔ bases/infrastructure/controllers/dex validated
 ✔ bases/infrastructure/controllers/flux-operator validated
 ✔ bases/infrastructure/controllers/keda validated
 ✔ bases/infrastructure/controllers/kube-prometheus-stack validated
 ✔ bases/infrastructure/controllers/kubescape validated
 ✔ bases/infrastructure/controllers/kubevirt validated
 ✔ bases/infrastructure/controllers/kyverno validated
 ✔ bases/infrastructure/controllers/loki validated
 ✔ bases/infrastructure/controllers/metrics-server validated
 ✔ bases/infrastructure/controllers/oauth2-proxy validated
 ✔ bases/infrastructure/controllers/openbao validated
 ✔ bases/infrastructure/controllers/opencost validated
 ✔ bases/infrastructure/controllers/reloader validated
 ✔ bases/infrastructure/controllers/testkube validated
 ✔ bases/infrastructure/controllers validated
 ✔ bases/infrastructure/controllers/tetragon validated
 ✔ bases/infrastructure/contro...

GitHub Actions: 🧱 Validate Scaffold / 0_Validate Scaffold.txt: feat(coredns): migrate docker-provider CoreDNS from Deployment to HelmRelease

Conclusion: failure

View job details

##[group]Run ksail --config ksail.yaml workload validate
 �[36;1mksail --config ksail.yaml workload validate�[0m
 shell: /usr/bin/bash -e {0}
 ##[endgroup]
 ✅ Validating kustomizations...
 ✔ bases/bootstrap validated
 ✔ bases/bootstrap/priority-classes validated
 ✔ bases/apps/homepage validated
 ✔ bases/infrastructure/alerts validated
 ✔ bases/infrastructure/certificates validated
 ✔ bases/infrastructure/cluster-policies validated
 ✔ bases/infrastructure/cluster-role-bindings validated
 ✔ bases/infrastructure/cluster-roles validated
 ✔ bases/apps/whoami validated
 ✔ bases/apps/headlamp validated
 ✔ bases/apps validated
 ✔ bases/infrastructure/controllers/alloy validated
 ✔ bases/infrastructure/cluster-secret-stores validated
 ✔ bases/infrastructure/controllers/auth-proxy validated
 ✔ bases/infrastructure/controllers/cert-manager validated
 ✔ bases/infrastructure/controllers/cilium validated
 ✔ bases/infrastructure/controllers/coredns validated
 ✔ bases/infrastructure/controllers/cloudnative-pg validated
 ✔ bases/infrastructure/controllers/external-secrets validated
 ✔ bases/infrastructure/controllers/dex validated
 ✔ bases/infrastructure/controllers/flux-operator validated
 ✔ bases/infrastructure/controllers/keda validated
 ✔ bases/infrastructure/controllers/kube-prometheus-stack validated
 ✔ bases/infrastructure/controllers/kubescape validated
 ✔ bases/infrastructure/controllers/kubevirt validated
 ✔ bases/infrastructure/controllers/kyverno validated
 ✔ bases/infrastructure/controllers/loki validated
 ✔ bases/infrastructure/controllers/metrics-server validated
 ✔ bases/infrastructure/controllers/oauth2-proxy validated
 ✔ bases/infrastructure/controllers/openbao validated
 ✔ bases/infrastructure/controllers/opencost validated
 ✔ bases/infrastructure/controllers/reloader validated
 ✔ bases/infrastructure/controllers/testkube validated
 ✔ bases/infrastructure/controllers validated
 ✔ bases/infrastructure/controllers/tetragon validated
 ✔ bases/infrastructure/contro...
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

Use Kustomize patches: to change shared bases from overlays; do not edit base resources indirectly or bypass the base→provider→cluster layering.

Files:

  • talos-local/cluster/disable-coredns.yaml
  • k8s/providers/docker/infrastructure/controllers/coredns/helm-repository.yaml
  • k8s/providers/docker/infrastructure/controllers/coredns/helm-release.yaml
  • k8s/providers/docker/infrastructure/controllers/coredns/kustomization.yaml
**/*

📄 CodeRabbit inference engine (AGENTS.md)

SHA-pin third-party GitHub Actions unless they are actions/*, github/*, or devantler-tech/*, which may use ref pins per zizmor.yml.

Files:

  • talos-local/cluster/disable-coredns.yaml
  • k8s/providers/docker/infrastructure/controllers/coredns/helm-repository.yaml
  • k8s/providers/docker/infrastructure/controllers/coredns/helm-release.yaml
  • k8s/providers/docker/infrastructure/controllers/coredns/kustomization.yaml
k8s/providers/**

📄 CodeRabbit inference engine (AGENTS.md)

Keep provider overlays in k8s/providers/ template-owned and update them upstream here rather than in an instance.

Files:

  • k8s/providers/docker/infrastructure/controllers/coredns/helm-repository.yaml
  • k8s/providers/docker/infrastructure/controllers/coredns/helm-release.yaml
  • k8s/providers/docker/infrastructure/controllers/coredns/kustomization.yaml
k8s/**/*.{yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

Before any manifest PR, validate Kubernetes YAML with ksail --config ksail.yaml workload validate and ksail --config ksail.prod.yaml workload validate; if KSail is unavailable, both overlays must build with kubectl kustomize k8s/clusters/local/ and kubectl kustomize k8s/clusters/prod/, and individual files should pass kubectl apply --dry-run=client -f <file>.

Files:

  • k8s/providers/docker/infrastructure/controllers/coredns/helm-repository.yaml
  • k8s/providers/docker/infrastructure/controllers/coredns/helm-release.yaml
  • k8s/providers/docker/infrastructure/controllers/coredns/kustomization.yaml
🪛 Trivy (0.69.3)
k8s/providers/docker/infrastructure/controllers/coredns/helm-repository.yaml

[warning] 6-7: User resources should not be placed in kube-system namespace

HelmRepository 'coredns' should not be set with 'kube-system' namespace

Rule: KSV-0037

Learn more

(IaC/Kubernetes)

k8s/providers/docker/infrastructure/controllers/coredns/helm-release.yaml

[warning] 18-107: User resources should not be placed in kube-system namespace

HelmRelease 'coredns' should not be set with 'kube-system' namespace

Rule: KSV-0037

Learn more

(IaC/Kubernetes)

🔇 Additional comments (4)
k8s/providers/docker/infrastructure/controllers/coredns/helm-repository.yaml (1)

1-8: LGTM!

k8s/providers/docker/infrastructure/controllers/coredns/helm-release.yaml (1)

47-49: 🗄️ Data Integrity & Integration | ⚡ Quick win

Confirm the hardcoded clusterIP matches the cluster's actual service subnet.

10.96.0.10 is the Talos default kube-dns address, but it's only correct if cluster.network.serviceSubnets hasn't been customized for this cluster. If the service subnet ever diverges from the default 10.96.0.0/12, this hardcoded IP would silently break DNS (Service creation would fail or use an out-of-range IP).

k8s/providers/docker/infrastructure/controllers/coredns/kustomization.yaml (1)

1-6: LGTM!

talos-local/cluster/disable-coredns.yaml (1)

1-4: LGTM!

Comment thread k8s/providers/docker/infrastructure/controllers/coredns/helm-release.yaml Outdated
cluster.coreDNS.disabled:true skips Talos's whole CoreDNS bootstrap on a
fresh cluster (not just the Deployment), so the docker-provider CI cluster
never gets a Talos-created coredns ServiceAccount/RBAC for the chart to
reuse. serviceAccount.create/rbac.create must stay true.
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Daily AI Assistant

Both threads verified and resolved in b8e2b04:

  • 🟠 Major (ServiceAccount/RBAC): confirmed — cluster.coreDNS.disabled: true skips Talos's entire CoreDNS bootstrap on a fresh cluster (not just the Deployment), so the docker-provider CI cluster never gets a Talos-created coredns ServiceAccount/ClusterRole/ClusterRoleBinding. My original "Talos already bootstraps it" comment was based on an already-running cluster where CoreDNS was never disabled — wrong premise for a fresh bootstrap with this patch applied from the start. Flipped serviceAccount.create/rbac.create to true so the chart owns its own identity, updated the header comment accordingly.
  • 🔵 Trivial (unbounded retries): verified against the repo's own convention — every other infra controller (kubescape, hcloud-csi, external-dns, hcloud-ccm, longhorn, origin-ca-issuer) uses retries: -1 for both install and upgrade remediation. This isn't a deviation, it's the established pattern for cluster-critical controllers — leaving as-is.

ksail --config ksail.yaml workload validate green (coredns overlay validates; the two unrelated pre-existing failures — testkube OCI fetch, external-secrets CRD YAML parse — reproduce identically on unmodified main).

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Daily AI Assistant

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

@devantler Sounds good, I'll review the latest changes now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@devantler

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

🤖 Generated by the Daily AI Assistant

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

@devantler Sure, I'll do a full review of all the changes in this PR now.

✅ Action performed

Full review finished.

@devantler devantler marked this pull request as ready for review July 9, 2026 03:10
@devantler devantler requested a review from a team as a code owner July 9, 2026 03:10
@devantler devantler merged commit ccfdc01 into main Jul 9, 2026
12 checks passed
@devantler devantler deleted the claude/coredns-helmrelease branch July 9, 2026 03:19
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.

Rework CoreDNS deployment into a helm-release

1 participant