Merge infra and k3 into one directory again

Since I don't have multiple terraform steps anymore it simply doesn't
make sense to me anymore to split all tasks into separate folders.
Instead I try to be as clear as possible in the README to make it easy
to follow the structure in the future without too much headache.
This commit is contained in:
2025-09-21 19:28:08 +02:00
parent fef383fed4
commit 7297892e18
32 changed files with 70 additions and 99 deletions

View File

@@ -0,0 +1,25 @@
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

View File

@@ -0,0 +1,19 @@
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

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

View File

@@ -0,0 +1,116 @@
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 = var.ssh_port, 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
}
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
}
}

View File

@@ -0,0 +1,23 @@
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])
}
output "private_network_cidr" {
value = local.network
}
output "private_network_nat" {
value = cidrhost(local.subnet_eu_central, 1)
}
output "ssh_port" {
value = var.ssh_port
}

View File

@@ -0,0 +1,49 @@
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 = []
}
variable "ssh_port" {
type = number
default = 1022
}

View File

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