Self Hosting

Free HTTPS for Kubernetes: Auto-Renewing Let's Encrypt Certificates

December 18, 2025
20 min read
Easy
K8s
Hetzner
Self-host
Fundamentals
Domain
Free HTTPS for Kubernetes: Auto-Renewing Let's Encrypt Certificates

Free HTTPS for Kubernetes: Auto-Renewing Let’s Encrypt Certificates

You have a cluster. You have a domain. Now it’s time to introduce them properly—with encryption, because we’re not savages running plaintext in 2025. This guide wires your domain through Hetzner DNS, points it at your floating IP, and hands off TLS certificate management to cert-manager. The result: automatic HTTPS with zero manual renewal headaches. Forever.

Init

What you need

Before diving in, ensure you have:

  • A running k3s cluster from the Hetzner Terraform setup

  • A domain registered with any provider (we’ll migrate nameservers)

  • kubectl configured against your cluster

  • Terraform with your existing cluster state

  • ping and curl command make remote requests

  • helm to install cert-manager

Apply

Setup DNS provider

Your domain registrar handles registration, but Hetzner will handle resolution. Head to your registrar’s dashboard and update the nameservers to:

  • helium.ns.hetzner.de

  • hydrogen.ns.hetzner.com

  • oxygen.ns.hetzner.com

Propagation Time

DNS propagation can take anywhere from seconds to 48 hours depending on your registrar and TTL settings—grab a coffee, or several

Why Hetzner DNS?

Using Hetzner's nameservers keeps your infrastructure consolidated. More importantly, it enables Terraform to manage DNS records alongside your cluster resources—single source of truth, single terraform apply. The alternative is juggling Cloudflare tokens, Route53 IAM policies, or manual record updates like it's 2010.

Setup DNS in terraform

Pre-require: floating IP output

If you built your cluster through Terraform following Self-host K8s article, this block should already exist in your kube.tf. If not, add it or replace with static IP address—we need the public IP programmatically available for DNS records.

kube.tf

HCL
data "hcloud_floating_ips" "all" {
  depends_on = [module.kube-hetzner]
}

output "floating_ip" {
  description = "Your public IP—point DNS here"
  value       = data.hcloud_floating_ips.all.floating_ips[0].ip_address
}

DNS definition

Now the actual DNS zone and records. We create an A record for the apex domain and a wildcard for subdomains—both pointing at your floating IP.

kube.tf

HCL
Base domain value****

Make sure you export variable

bash

Shell
export TF_VAR_base_domain="your-domain.com"

<-- Back to Blog <-- Back to Self Hosting