Move infra-setup and k3s-setup into dedicated directories

This changes makes it easier to differentiate and understand the
different parts of the kubernetes setup. On one hand we have the bare
infrastructure (servers, network, etc), on the other hand we have the
software (k3s in this case).

In the future we'll have a few more parts, like the minimal
configuration of the kubernetes cluster, e.g. with a cert-manager. This
is easier to manage with helm or terraform than with ansible. Therefore
it makes even more sense to split the responsibilities into dedicated
directories.
This commit is contained in:
2025-09-15 12:45:50 +02:00
parent dfcdc9797a
commit d96523a071
24 changed files with 89 additions and 59 deletions

View File

@@ -1,25 +0,0 @@
resource "hetznerdns_zone" "this" {
name = var.zone
ttl = var.zone_ttl
}
locals {
records = nonsensitive({
for record in var.records : "${record.type}#${record.name}#${md5(record.value)}" => {
for key, value in record : key => value
}
})
}
resource "hetznerdns_record" "this" {
for_each = local.records
zone_id = hetznerdns_zone.this.id
name = each.value.name
type = each.value.type
value = (each.value.type == "TXT"
? "\"${join("\" \"", [for c in chunklist(split("", each.value.value), 255) : join("", c)])}\""
: each.value.value
)
ttl = each.value.ttl
}

View File

@@ -1,19 +0,0 @@
variable "zone" {
type = string
}
variable "zone_ttl" {
type = number
default = 3600
}
variable "records" {
type = set(object({
name = string
value = string
type = string
ttl = optional(number, null)
}))
default = []
}

View File

@@ -1,10 +0,0 @@
terraform {
required_providers {
hetznerdns = {
source = "timohirt/hetznerdns"
version = "2.2.0"
}
}
}

View File

@@ -1,17 +0,0 @@
#cloud-config
packages:
- curl
users:
- name: cluster
shell: /bin/bash
runcmd:
# configure correct routing via NAT
- ip route add default via ${network_gateway}
- NIC=$(ifconfig | grep -q enp7s0 && echo enp7s0 || echo ens10)
- echo "[Match]" > /etc/systemd/network/10-$NIC.network
- echo "Name=$NIC" >> /etc/systemd/network/10-$NIC.network
- echo "[Network]" >> /etc/systemd/network/10-$NIC.network
- echo "DHCP=yes" >> /etc/systemd/network/10-$NIC.network
- echo "Gateway=${network_gateway}" >> /etc/systemd/network/10-$NIC.network
- sed -e "s/#DNS=/DNS=${dns_servers}/" -i /etc/systemd/resolved.conf
- systemctl restart systemd-resolved

View File

@@ -1,133 +0,0 @@
locals {
network = "10.0.0.0/16"
subnet_eu_central = "10.0.0.0/24"
servers = {
for idx, config in var.servers : "${var.name}-server-${idx + 1}" => merge(
config,
{
ip = cidrhost(local.subnet_eu_central, idx + 2)
first_ip = idx == 0 ? "" : cidrhost(local.subnet_eu_central, 2)
}
)
}
agents = merge([
for idx, config in var.agents : {
for n in range(0, config.count) : "${var.name}-agent-${idx + 1}-${n + 1}" => merge(
config,
{ ip = cidrhost(local.subnet_eu_central, 255 - (idx * 20) - n - 1) }
)
}
]...)
all_ips = ["0.0.0.0/0", "::/0"]
ping_firewall = var.ping_enabled ? { "ping" : [{ protocol = "icmp", port = null }] } : {}
k8s_firewall = { "kubernetes" : [{ port = "6443", source_ips = concat([local.network], var.kubernetes_exposed_ips) }] }
ssh_firewall = length(var.ssh_exposed_ips) > 0 ? { "ssh" : [{ port = 1022, source_ips = var.ssh_exposed_ips }] } : {}
service_firewalls = { for service, ports in var.public_tcp_services : service => [for port in ports : { port = port }] }
firewalls = merge(
local.ping_firewall,
local.k8s_firewall,
local.ssh_firewall,
local.service_firewalls
)
}
resource "hcloud_network" "this" {
name = var.name
ip_range = local.network
}
resource "hcloud_network_subnet" "this" {
type = "cloud"
network_id = hcloud_network.this.id
network_zone = "eu-central"
ip_range = local.subnet_eu_central
}
resource "hcloud_network_route" "this" {
network_id = hcloud_network.this.id
destination = "0.0.0.0/0"
gateway = cidrhost(local.subnet_eu_central, 2)
}
resource "random_string" "k3s_token" {
length = 100
special = false
}
resource "hcloud_firewall" "this" {
for_each = local.firewalls
name = each.key
dynamic "rule" {
for_each = each.value
content {
direction = lookup(rule.value, "direction", "in")
protocol = lookup(rule.value, "protocol", "tcp")
source_ips = lookup(rule.value, "source_ips", local.all_ips)
port = lookup(rule.value, "port")
}
}
}
resource "hcloud_server" "server" {
depends_on = [hcloud_network_subnet.this]
for_each = local.servers
lifecycle {
ignore_changes = [ user_data ]
}
name = each.key
image = "ubuntu-24.04"
server_type = each.value.type
location = each.value.location
ssh_keys = var.ssh_keys
public_net {
ipv4 = each.value.ipv4_id
ipv6 = each.value.ipv6_id
}
network {
network_id = hcloud_network.this.id
ip = each.value.ip
}
user_data = templatefile(
"${path.module}/server-init.yaml.tftpl",
{
network_ip_range = local.network
k3s_token = random_string.k3s_token.result
first_ip = each.value.first_ip
}
)
firewall_ids = [for firewall in hcloud_firewall.this : firewall.id]
}
resource "hcloud_server" "agent" {
depends_on = [hcloud_server.server]
for_each = local.agents
lifecycle {
ignore_changes = [ user_data ]
}
name = each.key
image = "ubuntu-24.04"
server_type = each.value.type
location = each.value.location
ssh_keys = var.ssh_keys
public_net {
ipv4_enabled = false
ipv6_enabled = false
}
network {
network_id = hcloud_network.this.id
ip = each.value.ip
}
user_data = templatefile(
"${path.module}/agent-init.yaml.tftpl",
{
server_ip = cidrhost(local.subnet_eu_central, 2)
network_gateway = cidrhost(local.subnet_eu_central, 1)
dns_servers = "8.8.8.8 8.8.4.4"
k3s_token = random_string.k3s_token.result
}
)
}

View File

@@ -1,11 +0,0 @@
output "server_ips_v4" {
value = [for key, value in hcloud_server.server : value.ipv4_address]
}
output "server_ips_v6" {
value = [for key, value in hcloud_server.server : value.ipv6_address]
}
output "agent_ips_v4" {
value = flatten([for key, value in hcloud_server.agent : value.network.*.ip])
}

View File

@@ -1,13 +0,0 @@
#cloud-config
packages:
- curl
users:
- name: cluster
shell: /bin/bash
runcmd:
# configure NAT
- echo '#!/bin/bash' > /etc/networkd-dispatcher/routable.d/10-eth0-post-up
- echo 'echo 1 > /proc/sys/net/ipv4/ip_forward' >> /etc/networkd-dispatcher/routable.d/10-eth0-post-up
- echo 'iptables -t nat -A POSTROUTING -s ${network_ip_range} -o eth0 -j MASQUERADE' >> /etc/networkd-dispatcher/routable.d/10-eth0-post-up
- chmod +x /etc/networkd-dispatcher/routable.d/10-eth0-post-up
- /etc/networkd-dispatcher/routable.d/10-eth0-post-up

View File

@@ -1,44 +0,0 @@
variable "name" {
type = string
}
variable "ssh_keys" {
type = list(string)
}
variable "servers" {
type = list(object({
ipv4_id = number
ipv6_id = number
type = string
location = string
}))
}
variable "agents" {
type = list(object({
count = optional(number, 1)
type = string
location = string
}))
}
variable "ping_enabled" {
type = bool
default = true
}
variable "public_tcp_services" {
type = map(list(string))
default = {}
}
variable "kubernetes_exposed_ips" {
type = list(string)
default = []
}
variable "ssh_exposed_ips" {
type = list(string)
default = []
}

View File

@@ -1,14 +0,0 @@
terraform {
required_providers {
hcloud = {
source = "hetznercloud/hcloud"
version = "1.50.0"
}
random = {
source = "hashicorp/random"
version = "3.7.1"
}
}
}