mysticaltech/terraform-hcloud-kube-hetzner

Optimized and Maintenance-free Kubernetes on Hetzner Cloud in one command!

HCL

3,938

3,236 commits

updated Oct 9, 2026

See the code

README

Kube-Hetzner logo

Kube-Hetzner

Production-ready Kubernetes on Hetzner Cloud

HA by default | Auto-upgrading | Cost-optimized

A healthy kube-hetzner cluster with Kubernetes system workloads running

A highly optimized, easy-to-operate Kubernetes cluster powered by k3s or RKE2 on openSUSE Leap Micro, deployed on Hetzner Cloud.

Go from an empty Hetzner project to a running cluster in four steps.

Terraform   OpenTofu   HCloud Provider   K3s   Docs   License   GitHub Stars


Highlights

  • Production-ready defaults: private networking, firewalls, CSI storage, ingress, certificate management, OS updates, and Kubernetes upgrades are integrated.
  • k3s or RKE2: k3s is the lightweight default; RKE2 is a first-class option for heavier and compliance-oriented environments.
  • Highly available and elastic: odd control-plane quorum, multi-location pools, static agents, and Cluster Autoscaler nodepools.
  • Immutable openSUSE nodes: Leap Micro is the default; MicroOS remains supported for existing clusters and explicit nodepool selection.
  • Flexible networking: Flannel, Calico, or Cilium; private-only NAT; dual-stack; Tailscale transport; Gateway API; and advanced multinetwork designs.
  • Plan-time guardrails: invalid topology and cross-variable combinations fail before infrastructure is created.
  • Evidence-backed releases: release claims are tied to live apply, upgrade, health, and destroy evidence in docs/v3-release-evidence.md.

Current release: v3.2.1 release notes | Changelog | 3.x upgrade guide | v2 to v3 migration

Quick Start

  1. Install OpenTofu or Terraform, Packer 1.16.0, kubectl, and hcloud. With Homebrew, install the other tools in one command:

    brew install opentofu kubectl hcloud
    
  2. Create a Hetzner Cloud project, create a Read & Write API token, and generate a passphrase-less SSH key (ssh-keygen -t ed25519).

  3. Run createkh. It creates your project folder, kube.tf, and the required Leap Micro images.

    Bash/Zsh:

    (tmp_script=$(mktemp) && trap 'rm -f "$tmp_script"' EXIT && curl -fsSL -o "$tmp_script" https://raw.githubusercontent.com/kube-hetzner/terraform-hcloud-kube-hetzner/master/scripts/create.sh && chmod +x "$tmp_script" && env -u KH_SOURCE_DIRECTORY "$tmp_script")
    

    Fish:

    set tmp_script (mktemp); curl -fsSL -o "$tmp_script" https://raw.githubusercontent.com/kube-hetzner/terraform-hcloud-kube-hetzner/master/scripts/create.sh; and chmod +x "$tmp_script"; and env -u KH_SOURCE_DIRECTORY bash "$tmp_script"; set run_status $status; rm -f "$tmp_script"; test $run_status -eq 0
    
  4. Edit kube.tf, remove example node pools you do not need, then deploy:

    cd <your-project-folder>
    tofu init --upgrade
    tofu plan
    tofu apply
    

    Use terraform instead of tofu if that is what you installed. Every option is listed in the generated configuration reference.

Choose a Topology

NeedRecommended starting point
Small development clusterOne control plane, one agent pool, automatic upgrades disabled.
Normal production HAThree control planes, two or more agents, one private Hetzner Network, restricted API and SSH sources.
Private-only clusterNAT router plus a private control-plane load balancer.
Secure operator accessTailscale node transport with public API and SSH sources closed.
More than 100 cloud nodesTailscale multinetwork with explicit primary/external network scopes.
Cilium Gateway APICilium, kube-proxy disabled, and cilium_gateway_api_enabled = true.
Heavy image-pull pressureembedded_registry_mirror.enabled = true on a mutually trusted cluster.

Read the topology recommendations and support matrix before choosing an advanced path.

Cloudflare Access/Tunnel is a documented external boundary for operator and application access. Cloudflare Mesh/WARP is not supported as kube-hetzner node transport. See the Cloudflare external-access example. For Gateway API, start with the Cilium example.

Documentation

docs/index.md is the complete documentation map. Start with the path that matches your task:

TaskRead this
Configure a clusterkube.tf.example, Terraform inputs and outputs, operator reference
Operate a clusterDay-2 operations, SSH and access, backup and restore
Upgrade Kubernetes, the OS, or the moduleUpgrades
Debug a broken cluster or expired certificatesTroubleshooting
Copy a working configuration patternRecipes and examples/
Design networking or private egressTopology recommendations, private-network egress
Review security and artifact trustSELinux, installation supply chain
Add a Hetzner Robot serverDedicated server integration

Upgrading from v2

Do not blind-apply a v2 to v3 upgrade. Start with MIGRATION.md for the compatibility contract and variable map, then follow the step-by-step migration guide. Back up state and reject any plan with unexplained destroy or replacement actions.

The fastest assisted path is /migrate-v2-to-v3, which rewrites the configuration and runs the protected-infrastructure plan gate without applying changes.

AI-Assisted Operations

Install the project skills in Claude Code, Codex, Cursor, or another skills-compatible agent:

npx skills add kube-hetzner/terraform-hcloud-kube-hetzner
SkillPurpose
/kh-assistantConfiguration and troubleshooting help grounded in the current repository.
/migrate-v2-to-v3 <terraform-root>Guided migration with protected-infrastructure plan review.
/upgrade-cluster <terraform-root>Safety-first module and Kubernetes upgrade workflow.
/debug-node <server>Rescue workflow for unreachable nodes, SSH, cloud-init, and provisioning failures.
/test-changesRepository-native Terraform/OpenTofu validation gates.

Remove a Cluster

Use the state-aware destroy wrapper first. It handles known dependency races and reports possible Hetzner orphans without deleting them outside Terraform:

(tmp_script=$(mktemp) && trap 'rm -f "$tmp_script"' EXIT && curl -fsSL -o "$tmp_script" https://raw.githubusercontent.com/kube-hetzner/terraform-hcloud-kube-hetzner/master/scripts/destroy.sh && chmod +x "$tmp_script" && "$tmp_script")

Forceful cleanup fallback:

(tmp_script=$(mktemp) && trap 'rm -f "$tmp_script"' EXIT && curl -fsSL -o "$tmp_script" https://raw.githubusercontent.com/kube-hetzner/terraform-hcloud-kube-hetzner/master/scripts/cleanup.sh && chmod +x "$tmp_script" && "$tmp_script")

[!WARNING] cleanup.sh resolves the Terraform HCloud token, activates the matching cluster-named context, and treats that project as dedicated to the cluster. Its dry run includes unrelated runtime resources in the same project; volumes, snapshots, DNS zones, and Storage Boxes require separate opt-in. If Terraform was applied with -var="hcloud_token=...", export that same value as TF_VAR_hcloud_token or pass it through --var-file before cleanup. Review the plan before typing the cluster name to confirm. --yes skips that typed confirmation and is intended only for controlled automation.

Fish shell version
set tmp_script (mktemp); curl -fsSL -o "$tmp_script" https://raw.githubusercontent.com/kube-hetzner/terraform-hcloud-kube-hetzner/master/scripts/cleanup.sh; and chmod +x "$tmp_script"; and bash "$tmp_script"; set run_status $status; rm -f "$tmp_script"; test $run_status -eq 0
Save as cleanupkh (Bash/Zsh)
cleanupkh() { (tmp_script=$(mktemp) && trap 'rm -f "$tmp_script"' EXIT && curl -fsSL -o "$tmp_script" https://raw.githubusercontent.com/kube-hetzner/terraform-hcloud-kube-hetzner/master/scripts/cleanup.sh && chmod +x "$tmp_script" && "$tmp_script" "$@"); }

Why Kube-Hetzner

Hetzner Cloud provides high-value infrastructure across Europe and the US. Kube-Hetzner combines it with:

  • openSUSE Leap Micro, an immutable OS with transactional updates and BTRFS rollback.
  • k3s, a lightweight certified Kubernetes distribution with integrated operational components.
  • RKE2, a hardened Kubernetes distribution for heavier deployments.
  • Terraform and OpenTofu, keeping infrastructure explicit, reviewable, and reproducible.

Kube-Hetzner is not affiliated with Hetzner.

Community

Questions, ideas, and community support belong in GitHub Discussions. Issues and pull requests are welcome. For contribution setup and repository gates, read CONTRIBUTING.md.

Support This Project

Kube-Hetzner is free and open source. If it saves you engineering time or infrastructure cost, please help fund its continued development.

Sponsor Kube-Hetzner on GitHub



Sponsorship directly supports issue response, new capabilities, documentation, security maintenance, and real-cluster release testing.

Every contribution helps keep Kube-Hetzner reliable, current, and available to everyone.


Acknowledgements

  • k-andy, the starting point for this project.
  • Rancher, for k3s and RKE2.
  • openSUSE, for Leap Micro and MicroOS.
  • HashiCorp and OpenTofu, for the infrastructure tooling ecosystem.
  • The contributors and operators who report issues, improve the module, and test real upgrades.

Hetzner - Server, Cloud, Hosting



Thanks to Hetzner for supporting Kube-Hetzner with cloud credits.


License

Released under the MIT License.

hcloud
hetzner-cloud
k3s
k8s
kubernetes
rke2
terraform

mysticaltech/terraform-hcloud-kube-hetzner

Optimized and Maintenance-free Kubernetes on Hetzner Cloud in one command!

HCL

3,938

3,236 commits

updated Oct 9, 2026

See the code

README

Kube-Hetzner logo

Kube-Hetzner

Production-ready Kubernetes on Hetzner Cloud

HA by default | Auto-upgrading | Cost-optimized

A healthy kube-hetzner cluster with Kubernetes system workloads running

A highly optimized, easy-to-operate Kubernetes cluster powered by k3s or RKE2 on openSUSE Leap Micro, deployed on Hetzner Cloud.

Go from an empty Hetzner project to a running cluster in four steps.

Terraform   OpenTofu   HCloud Provider   K3s   Docs   License   GitHub Stars


Highlights

  • Production-ready defaults: private networking, firewalls, CSI storage, ingress, certificate management, OS updates, and Kubernetes upgrades are integrated.
  • k3s or RKE2: k3s is the lightweight default; RKE2 is a first-class option for heavier and compliance-oriented environments.
  • Highly available and elastic: odd control-plane quorum, multi-location pools, static agents, and Cluster Autoscaler nodepools.
  • Immutable openSUSE nodes: Leap Micro is the default; MicroOS remains supported for existing clusters and explicit nodepool selection.
  • Flexible networking: Flannel, Calico, or Cilium; private-only NAT; dual-stack; Tailscale transport; Gateway API; and advanced multinetwork designs.
  • Plan-time guardrails: invalid topology and cross-variable combinations fail before infrastructure is created.
  • Evidence-backed releases: release claims are tied to live apply, upgrade, health, and destroy evidence in docs/v3-release-evidence.md.

Current release: v3.2.1 release notes | Changelog | 3.x upgrade guide | v2 to v3 migration

Quick Start

  1. Install OpenTofu or Terraform, Packer 1.16.0, kubectl, and hcloud. With Homebrew, install the other tools in one command:

    brew install opentofu kubectl hcloud
    
  2. Create a Hetzner Cloud project, create a Read & Write API token, and generate a passphrase-less SSH key (ssh-keygen -t ed25519).

  3. Run createkh. It creates your project folder, kube.tf, and the required Leap Micro images.

    Bash/Zsh:

    (tmp_script=$(mktemp) && trap 'rm -f "$tmp_script"' EXIT && curl -fsSL -o "$tmp_script" https://raw.githubusercontent.com/kube-hetzner/terraform-hcloud-kube-hetzner/master/scripts/create.sh && chmod +x "$tmp_script" && env -u KH_SOURCE_DIRECTORY "$tmp_script")
    

    Fish:

    set tmp_script (mktemp); curl -fsSL -o "$tmp_script" https://raw.githubusercontent.com/kube-hetzner/terraform-hcloud-kube-hetzner/master/scripts/create.sh; and chmod +x "$tmp_script"; and env -u KH_SOURCE_DIRECTORY bash "$tmp_script"; set run_status $status; rm -f "$tmp_script"; test $run_status -eq 0
    
  4. Edit kube.tf, remove example node pools you do not need, then deploy:

    cd <your-project-folder>
    tofu init --upgrade
    tofu plan
    tofu apply
    

    Use terraform instead of tofu if that is what you installed. Every option is listed in the generated configuration reference.

Choose a Topology

NeedRecommended starting point
Small development clusterOne control plane, one agent pool, automatic upgrades disabled.
Normal production HAThree control planes, two or more agents, one private Hetzner Network, restricted API and SSH sources.
Private-only clusterNAT router plus a private control-plane load balancer.
Secure operator accessTailscale node transport with public API and SSH sources closed.
More than 100 cloud nodesTailscale multinetwork with explicit primary/external network scopes.
Cilium Gateway APICilium, kube-proxy disabled, and cilium_gateway_api_enabled = true.
Heavy image-pull pressureembedded_registry_mirror.enabled = true on a mutually trusted cluster.

Read the topology recommendations and support matrix before choosing an advanced path.

Cloudflare Access/Tunnel is a documented external boundary for operator and application access. Cloudflare Mesh/WARP is not supported as kube-hetzner node transport. See the Cloudflare external-access example. For Gateway API, start with the Cilium example.

Documentation

docs/index.md is the complete documentation map. Start with the path that matches your task:

TaskRead this
Configure a clusterkube.tf.example, Terraform inputs and outputs, operator reference
Operate a clusterDay-2 operations, SSH and access, backup and restore
Upgrade Kubernetes, the OS, or the moduleUpgrades
Debug a broken cluster or expired certificatesTroubleshooting
Copy a working configuration patternRecipes and examples/
Design networking or private egressTopology recommendations, private-network egress
Review security and artifact trustSELinux, installation supply chain
Add a Hetzner Robot serverDedicated server integration

Upgrading from v2

Do not blind-apply a v2 to v3 upgrade. Start with MIGRATION.md for the compatibility contract and variable map, then follow the step-by-step migration guide. Back up state and reject any plan with unexplained destroy or replacement actions.

The fastest assisted path is /migrate-v2-to-v3, which rewrites the configuration and runs the protected-infrastructure plan gate without applying changes.

AI-Assisted Operations

Install the project skills in Claude Code, Codex, Cursor, or another skills-compatible agent:

npx skills add kube-hetzner/terraform-hcloud-kube-hetzner
SkillPurpose
/kh-assistantConfiguration and troubleshooting help grounded in the current repository.
/migrate-v2-to-v3 <terraform-root>Guided migration with protected-infrastructure plan review.
/upgrade-cluster <terraform-root>Safety-first module and Kubernetes upgrade workflow.
/debug-node <server>Rescue workflow for unreachable nodes, SSH, cloud-init, and provisioning failures.
/test-changesRepository-native Terraform/OpenTofu validation gates.

Remove a Cluster

Use the state-aware destroy wrapper first. It handles known dependency races and reports possible Hetzner orphans without deleting them outside Terraform:

(tmp_script=$(mktemp) && trap 'rm -f "$tmp_script"' EXIT && curl -fsSL -o "$tmp_script" https://raw.githubusercontent.com/kube-hetzner/terraform-hcloud-kube-hetzner/master/scripts/destroy.sh && chmod +x "$tmp_script" && "$tmp_script")

Forceful cleanup fallback:

(tmp_script=$(mktemp) && trap 'rm -f "$tmp_script"' EXIT && curl -fsSL -o "$tmp_script" https://raw.githubusercontent.com/kube-hetzner/terraform-hcloud-kube-hetzner/master/scripts/cleanup.sh && chmod +x "$tmp_script" && "$tmp_script")

[!WARNING] cleanup.sh resolves the Terraform HCloud token, activates the matching cluster-named context, and treats that project as dedicated to the cluster. Its dry run includes unrelated runtime resources in the same project; volumes, snapshots, DNS zones, and Storage Boxes require separate opt-in. If Terraform was applied with -var="hcloud_token=...", export that same value as TF_VAR_hcloud_token or pass it through --var-file before cleanup. Review the plan before typing the cluster name to confirm. --yes skips that typed confirmation and is intended only for controlled automation.

Fish shell version
set tmp_script (mktemp); curl -fsSL -o "$tmp_script" https://raw.githubusercontent.com/kube-hetzner/terraform-hcloud-kube-hetzner/master/scripts/cleanup.sh; and chmod +x "$tmp_script"; and bash "$tmp_script"; set run_status $status; rm -f "$tmp_script"; test $run_status -eq 0
Save as cleanupkh (Bash/Zsh)
cleanupkh() { (tmp_script=$(mktemp) && trap 'rm -f "$tmp_script"' EXIT && curl -fsSL -o "$tmp_script" https://raw.githubusercontent.com/kube-hetzner/terraform-hcloud-kube-hetzner/master/scripts/cleanup.sh && chmod +x "$tmp_script" && "$tmp_script" "$@"); }

Why Kube-Hetzner

Hetzner Cloud provides high-value infrastructure across Europe and the US. Kube-Hetzner combines it with:

  • openSUSE Leap Micro, an immutable OS with transactional updates and BTRFS rollback.
  • k3s, a lightweight certified Kubernetes distribution with integrated operational components.
  • RKE2, a hardened Kubernetes distribution for heavier deployments.
  • Terraform and OpenTofu, keeping infrastructure explicit, reviewable, and reproducible.

Kube-Hetzner is not affiliated with Hetzner.

Community

Questions, ideas, and community support belong in GitHub Discussions. Issues and pull requests are welcome. For contribution setup and repository gates, read CONTRIBUTING.md.

Support This Project

Kube-Hetzner is free and open source. If it saves you engineering time or infrastructure cost, please help fund its continued development.

Sponsor Kube-Hetzner on GitHub



Sponsorship directly supports issue response, new capabilities, documentation, security maintenance, and real-cluster release testing.

Every contribution helps keep Kube-Hetzner reliable, current, and available to everyone.


Acknowledgements

  • k-andy, the starting point for this project.
  • Rancher, for k3s and RKE2.
  • openSUSE, for Leap Micro and MicroOS.
  • HashiCorp and OpenTofu, for the infrastructure tooling ecosystem.
  • The contributors and operators who report issues, improve the module, and test real upgrades.

Hetzner - Server, Cloud, Hosting



Thanks to Hetzner for supporting Kube-Hetzner with cloud credits.


License

Released under the MIT License.

hcloud
hetzner-cloud
k3s
k8s
kubernetes
rke2
terraform

Significant stargazers

(top 24 of 56)

Miguel Grinberg

12,947 followers · starred Aug 2025

Wolf Vollprecht

700 followers · starred Dec 2022

Ahmed Kamal

67 followers · starred Apr 2023

Aleksandr Razumov

404 followers · starred Jul 2026