Terraform
Norn uses Terraform to provision Kubernetes clusters across multiple cloud providers. The infrastructure code supports Hetzner, DigitalOcean, and Vultr.
Directory Structure
infra/terraform/
├── main.tf
├── variables.tf
├── outputs.tf
└── modules/
├── hetzner/
├── digitalocean/
├── vultr/
└── k3s-node/main.tf: Root module that orchestrates cluster provisioningvariables.tf: Input variables for configurationoutputs.tf: Exported values (node IPs, cluster endpoints)modules/: Reusable components for each cloud provider and k3s node configuration
Modules
Cloud Provider Modules
hetzner: Hetzner Cloud resources (servers, networks)digitalocean: DigitalOcean resources (droplets, VPCs)vultr: Vultr resources (instances)
k3s-node Module
Generates cloud-init templates that:
- Install k3s on the node
- Configure server or agent role
- Enroll the node in Tailscale for mesh networking
Configuration
The nodes variable defines the cluster topology as a map of objects:
nodes = {
"node-1" = {
provider = "hetzner"
region = "nbg1"
size = "cx11"
role = "server"
}
"node-2" = {
provider = "digitalocean"
region = "nyc3"
size = "s-1vcpu-1gb"
role = "agent"
}
}Validation Rules
provider: Must behetzner,digitalocean, orvultrrole: Must beserveroragent- At least one
servernode is required
Provider Credentials
All provider tokens are marked sensitive:
hcloud_token: Hetzner Cloud API tokendo_token: DigitalOcean API tokenvultr_api_key: Vultr API key
SSH key IDs must be configured for each provider to enable access to provisioned nodes.
Cluster Initialization
The first server node initializes the k3s cluster. Additional server nodes join in HA mode. Agent nodes join via the server's API endpoint.
Variables
k3s_token: Shared secret for cluster join authenticationtailscale_auth_key: Auth key for enrolling nodes in Tailscale mesh
Both values are sensitive and should be managed via environment variables or a .tfvars file excluded from version control.
Cloud-Init
The k3s-node module generates cloud-init user data that:
- Installs k3s as server or agent
- Configures cluster join parameters (token, server URL)
- Enrolls the node in Tailscale for private networking
Server nodes use the k3s installation script with --cluster-init for the first server, or --server with the existing server URL for additional servers. Agent nodes use --agent and connect to the server API.
CLI Integration
The Norn CLI provides a command to initialize the cluster:
norn cluster initThis command:
- Runs
terraform initto download provider plugins - Runs
terraform applywith the configured variables - Waits for cluster readiness
Outputs
Terraform outputs include:
- Node IP addresses (public and private)
- Cluster API endpoint
- SSH connection details
These outputs are used by the CLI and API to interact with the provisioned cluster.