{"id":17095204,"url":"https://github.com/fnkr/hcloud-k8s","last_synced_at":"2025-04-12T23:14:21.127Z","repository":{"id":47098966,"uuid":"333218240","full_name":"fnkr/hcloud-k8s","owner":"fnkr","description":"Terraform module and Ansible playbook to provision Kubernetes clusters on Hetzner Cloud.","archived":false,"fork":false,"pushed_at":"2021-10-17T11:53:56.000Z","size":658,"stargazers_count":12,"open_issues_count":0,"forks_count":5,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-12T23:14:14.961Z","etag":null,"topics":["ansible","ansible-playbook","hcloud","hetzner","hetzner-cloud","kubernetes","kubernetes-cluster","terraform","terraform-module"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fnkr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-01-26T21:10:43.000Z","updated_at":"2025-02-23T20:51:23.000Z","dependencies_parsed_at":"2022-09-03T19:11:09.413Z","dependency_job_id":null,"html_url":"https://github.com/fnkr/hcloud-k8s","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fnkr%2Fhcloud-k8s","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fnkr%2Fhcloud-k8s/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fnkr%2Fhcloud-k8s/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fnkr%2Fhcloud-k8s/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fnkr","download_url":"https://codeload.github.com/fnkr/hcloud-k8s/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248643006,"owners_count":21138355,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","ansible-playbook","hcloud","hetzner","hetzner-cloud","kubernetes","kubernetes-cluster","terraform","terraform-module"],"created_at":"2024-10-14T14:26:09.384Z","updated_at":"2025-04-12T23:14:21.110Z","avatar_url":"https://github.com/fnkr.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hcloud-k8s\n\nThis repository contains a Terraform module and Ansible playbook to provision\n[Kubernetes](https://kubernetes.io) clusters on [Hetzner Cloud](https://hetzner.cloud).\n\n## Features\n\n* High availability: creates three control nodes and three worker nodes\n* etcd stacked on control plane nodes\n* containerd container runtime\n* Installs [Hetzner Cloud Controller Manager](https://github.com/hetznercloud/hcloud-cloud-controller-manager)\n* Installs [Hetzner Cloud Container Storage Interface](https://github.com/hetznercloud/csi-driver)\n* Uses placement groups to spread servers across a datacenter\n* Uses Hetzner Cloud Networks for all traffic between nodes\n* Uses Cilium with native routing through Hetzner Cloud Networks\n* Uses Cilium's WireGuard integration to encrypt traffic between pods\n* Creates Hetzner Cloud Load Balancer for traffic to K8s API\n* Creates Hetzner Cloud Load Balancer for traffic to worker nodes (ingress)\n* Creates Hetzner Cloud Firewall to restrict inbound traffic to servers\n* Installs [NGINX Ingress Controller](https://kubernetes.github.io/ingress-nginx/) as DaemonSet\n* Installs [cert-manager](https://cert-manager.io/)\n* Installs Ceph client\n\nMany features are optional, customizable and might be turned on or off by default.\nSee [VARIABLES.md](VARIABLES.md) for details.\n\n## Prerequisites\n\nInstructions should work on Linux and macOS.\nI suggest using the Subsystem for Linux (WSL2) on Windows.\nMake sure the following tools are installed before proceeding:\n\n* Terraform\n* Ansible\n* kubectl\n\n## Backwards compatibility\n\nThis project is in early development. It works, but there is still a lot to do. \nEach commit in the main branch is potentially breaking (might requires recreating the cluster).\nAs soon as there is a stable version, it will be tagged `v1.0.0`.\nTags should then be non-breaking until the next major version bump (`v2.0.0`).\n\n## Ansible\n\nIt is recommended to use the Ansible version and packages from `requirements.txt`.\n\n```\npython3 -m venv venv\nvenv/bin/pip install -r requirements.txt\n. venv/bin/activate\n```\n\n\n## Getting started\n\n**1)** Generate Read \u0026 Write API token\n\nOpen Hetzner Cloud Console \u003e Select Project \u003e Security \u003e API tokens \u003e Generate API token\n\nNote that the cluster will continue using this API token, even after Terraform and Ansible is done.\nIf the API token is deleted from Hetzner Cloud, the cluster will stop functioning.\n\n**2)** Add your SSH key\n\nOpen Hetzner Cloud Console \u003e Select Project \u003e Security \u003e SSH keys \u003e Add SSH key\n\nTerraform and Ansible will use this key to connect to servers.\nMake sure that the key is available on your local machine and loaded in ssh-agent (if the key is encrypted).\n\n**3)** Copy example configuration\n\n```\ncp terraform.tfvars.example terraform.tfvars\n```\n\nChange at least the following values:\n\n`hcloud_token`: Hetzner Cloud API token created during step 1  \n`cluster_authorized_ssh_keys`: Name of the SSH key added to Hetzner Cloud during step 2\n\nTurn on/off features, customize topology, ..., e.g.:\n\n```hcl\ninstall_hcloud_ccm   = true\ninstall_hcloud_csi   = true\ninstall_ceph_client  = true\ninstall_cert_manager = true\n```\n\nSee [VARIABLES.md](VARIABLES.md) for details.\n\n**4)** Provision K8s cluster\n\n```\nterraform init\nterraform apply -auto-approve\nansible-playbook ansible.yaml\n```\n\n**5)** Update kube client configuration\n\nThis will add the cluster to your local `~/.kube/config`.\n\n```\nansible-playbook kubeconfig.yaml\n```\n\nTest if connection works. Replace `testkube` with the `cluster_name` of your cluster.\n\n```\nkubectl --context testkube get all --all-namespaces\n```\n\n**6)** Watch your new cluster\n\nIt might take a minute until all pods are up.\n\n```\nwatch kubectl get all --all-namespaces\n```\n\n**7)** Delete your cluster\n\nYou can use this command to destroy your cluster.\nIt will delete all servers, load balancers and networks created by Terraform.\nIt will not delete anything created by Kubernetes (e.g. volumes created using persistent volume claims).\n\n```\nterraform destroy -auto-approve\n```\n\nDestroy cluster without destroying the infrastructure (factory-reset all servers):\n\n```bash\nexport HCLOUD_TOKEN=\"$(grep ^hcloud_token terraform.tfvars | awk -F '\"' '{print $2}')\"\nhcloud server list -o noheader -o columns=name | grep ^testkube- | xargs -n 1 hcloud server rebuild --image=ubuntu-20.04\n```\n\n## Working with multiple state/var files\n\n```\nterraform apply -var-file production.tfvars -state production.tfstate\nTF_STATE=production.tfstate ansible-playbook ansible.yaml\nTF_STATE=production.tfstate ansible-playbook kubeconfig.yaml\n```\n\n## Connecting to control node load balancer via internal network and proxy\n\nIf the public interface of the control node load balancer is disabled\nit might be useful to connect through a proxy. The installation of such a proxy is not part of this project.\n\nThe proxy would be located in the same internal network that the control node load balancer is in.\nThe `kubeconfig.yaml` playbook (which is a helper playbook that updates your local kube config)\nsupports this using the `KUBE_PROXY` and `KUBE_INTERNAL` environment variables.\n\nIf `KUBE_PROXY` is set, Kubernetes clients will be configured to make connections to the cluster\nthrough the specified proxy. If the option is used, the playbook will also extend the embedded trust store\nfor this Kubernetes configuration with the current set of certificates present in your local trust store\nin order to make HTTPS proxies work.\n\nIf `KUBE_INTERNAL` is set, internal (private) IP addresses of servers and load balancers will be used.\n\n```\nKUBE_PROXY=https://user:token@proxy.example.com KUBE_INTERNAL=1 ansible-playbook kubeconfig.yaml\n```\n\n## Minimal cluster\n\nBy default, a cluster with multiple control nodes, worker nodes and load balancers will be created.\nIf you just want a simple (non-HA) cluster for development/testing,\nyou can remove any additional servers and load balancers:\n\n```hcl\ncluster_controlnode_types     = [\"cx21\"]\ncluster_controlnode_locations = [\"nbg1\"]\ncluster_workernode_types      = []\ncluster_workernode_locations  = []\ncluster_controllb_types       = []\ncluster_controllb_locations   = []\ncluster_workerlb_types        = []\ncluster_workerlb_locations    = []\n```\n\n* If there are no worker nodes, the master taint will be removed from control nodes automatically,\n  so they can be used as worker nodes. (Not recommended for production.)\n* If there are no control node load balancers, the IP from the first control node in the same location,\n  or the first one if none exists in the same location, will be used.\n  (Breaks high availability, not recommended for production.)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffnkr%2Fhcloud-k8s","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffnkr%2Fhcloud-k8s","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffnkr%2Fhcloud-k8s/lists"}