Files
base-infra/infra/modules/hetzner/kubernetes/main.tf
Felix Nehrke d96523a071 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.
2025-09-15 14:47:19 +02:00

134 lines
3.6 KiB
HCL

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
}
)
}