Highly Available k3s on Hetzner Cloud with Terraform & GitOps
k3s-nebula is a production-ready infrastructure stack for deploying a fault-tolerant k3s cluster on Hetzner Cloud. It is designed for simplicity, cost-effectiveness, and GitOps-native workflows.
Maintained by WebTree
- High Availability: Multi-control plane setup with HAProxy load balancing
- Cost Effective: Runs on Hetzner Cloud (starting ~€20/mo for HA)
- GitOps Ready: Pre-configured with ArgoCD for declarative management
- Secure:
- Private networking for all nodes
- OIDC authentication via Keycloak
- Automatic TLS with Let's Encrypt & Traefik
- SSH keys & secrets managed via AWS SSM
- Modular: Split into
infrastructure(hardware) andconfiguration(k8s resources)
graph TD
subgraph Hetzner Cloud
LB[Load Balancer] --> CP1[Control Plane 1]
LB --> CP2[Control Plane 2]
CP1 --- LAN[Private Network]
CP2 --- LAN
end
subgraph External
DB[(PostgreSQL)]
S3[(AWS S3 State)]
SSM[(AWS SSM Secrets)]
end
CP1 --> DB
CP2 --> DB
Terraform --> S3
Terraform --> SSM
- Terraform >= 1.5.0
- AWS Account (for S3 state & SSM secrets)
- Hetzner Cloud Account
- Domain name managed via AWS Route53
Create a terraform.tfvars file in cluster-infrastructure:
env = "prod"
cluster_name = "my-cluster"
hcloud_token_ssm_path = "/hetzner/token"
ssh_public_keys = ["ssh-ed25519 AAA..."]
# ... other required variablesDeploy:
cd cluster-infrastructure
terraform init
terraform applyCreate a terraform.tfvars file in cluster-configuration:
base_domain = "example.com"
argocd_domain = "argocd.example.com"
# ... other required variablesDeploy:
cd cluster-configuration
terraform init
terraform apply- Operations Guide: Day-2 operations, upgrades, and maintenance
- Developer Guide: How to extend and contribute
- Troubleshooting: Common issues and fixes
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0) - see the LICENSE file for details.