Kubernetes cluster provisioning using Terraform.
Kubernetes cluster setup automation
This is part of the Hobby Kube project. Functionality of the modules is described in the guide.
Deploy a secure Kubernetes cluster on Hetzner Cloud, Scaleway, DigitalOcean or Packet using Terraform.
Setup
Requirements
The following packages are required to be installed locally:
brew install terraform kubectl jq wireguard-tools
Modules are using ssh-agent for remote operations. Add your SSH key with ssh-add -K if Terraform repeatedly fails to connect to remote hosts.
Configuration
Important: Modify only main.tf in project root, comment or uncomment sections as needed. All variables in variables.tf can be set either directly or from environment variable.
Export the following environment variables depending on the modules you're using:
Set number of hosts (nodes)
export TFVARnode_count=3
Set number of etcd members
The first N nodes will be part of the etcd cluster. 3 or 5 are good values, see here.
export TFVARetcdnodecount=3
Using Hetzner Cloud as provider
export TFVARhcloud_token=<token>
export TFVARhcloudsshkeys=<keys>
export TFVARhcloudsshkeys='["<description-key1>", "<description-key2>"]'
Defaults:
export TFVARhcloud_location="nbg1"
export TFVARhcloud_type="cx22"
export TFVARhcloud_image="ubuntu-24.04"
SSH keys are referenced by their description. Visit the Hetzner Cloud console at https://console.hetzner.cloud/projects/<project-id>/access/sshkeys
Using Scaleway as provider
export TFVARscalewayorganizationid=<organization_id>
export TFVARscalewayaccesskey=<access_key> # can be omitted for now
export TFVARscalewaysecretkey=<secret_key>
Defaults:
export TFVARscaleway_z
export TFVARscaleway_type="DEV1-S"
export TFVARscaleway_image="Ubuntu 24.04 Noble Numbat"
export TFVARscalewayimagearchitecture="x86_64"
Using DigitalOcean as provider
export TFVARdigitalocean_token=<token>
export TFVARdigitaloceansshkeys=<keys>
export TFVARdigitaloceansshkeys='["<id-key1>", "<id-key2>"]'
Defaults:
export TFVARdigitalocean_region="fra1"
export TFVARdigitalocean_size="1gb"
export TFVARdigitalocean_image="ubuntu-24-04-x64"
You can get SSH key IDs using this API.
Using Packet as provider
export TFVARpacketauthtoken=<token>
export TFVARpacketprojectid=<uuid>
Defaults:
export TFVARpacket_facility="sjc1"
export TFVARpacket_plan="c1.small.x86"
export TFVARpacketoperatingsystem="ubuntu2404"
Using vSphere as provider
export TFVARvsphere_server=<FQDN or IP of vCenter Server>
export TFVARvsphere_datacenter=<vSphere Datacenter Name>
export TFVARvsphere_cluster=<vSphere Cluster Name>
export TFVARvsphere_network=<vSphere Network Name>
export TFVARvsphere_datastore=<vSphere Datastore Name>
export TFVARvspherevmtemplate=<vSphere VM Template Name>
export TFVARvsphere_user=<vSphere Admin Username>
export TFVARvsphere_password=<vSphere Admin Password>
Defaults:
export TFVARvspherevmlinked_clone=false
export TFVARvspherevmnum_cpus="2"
export TFVARvspherevmmemory="2048"
Template VM needs to pre-configured so that root can login using SSH key.
Using UpCloud as provider
export TFVARupcloud_username=<UpCloud API account username>
export TFVARupcloud_password=<UpCloud API account password>
export TFVARupcloudsshkeys='["<PUBLIC KEY HERE>"]'
Defaults:
export TFVARupcloud_z
export TFVARupcloud_plan="1xCPU-2GB"
export TFVARupclouddisktemplate="Ubuntu Server 24.04 LTS (Noble Numbat)"
You will need API credentials to use the UpCloud terraform provider, see https://upcloud.com/community/tutorials/getting-started-upcloud-api/ for more info.
Using Cloudflare for DNS entries
export TFVARdomain=<domain> # e.g. example.org
export TFVARcloudflareapitoken=<token>
Using Amazon Route 53 for DNS entries
export TFVARdomain=<domain> # e.g. example.org shall be already added to hosted zones.
export TFVARawsaccesskey=<ACCESS_KEY>
export TFVARawssecretkey=<SECRET_KEY>
export TFVARaws_region=<region> # e.g. eu-west-1
Install additional APT packages
Each provider takes an optional variable to install further packages during provisioning:
module "provider" {
# ...
apt_packages = ["ceph-common", "nfs-common"]
}
Add more firewall rules
Security/ufw takes an optional variable to add custom firewall rules during provisioning:
module "firewall" {
# ...
additional_rules = ["allow 1194/udp", "allow ftp"]
}
Execute
From the root of this project...
# fetch the required modules
$ terraform init
see what terraform apply will do
$ terraform plan
execute it
$ terraform apply
Using modules independently
Modules in this repository can be used independently:
module "kubernetes" {
source = "github.com/hobby-kube/provisioning/service/kubernetes"
# Or to pin a certain commit # source = "git::https://github.com/hobby-kube/provisioning.git//service/kubernetes?ref=800d5d5031245cf31a803a147eaa40a0de0573f1" }
After adding this to your plan, run terraform get to fetch the module.