locals { ssh_source_ips = var.restrict_api_ssh_to_tailnet ? [var.tailnet_cidr] : var.allowed_ssh_ips api_source_ips = var.restrict_api_ssh_to_tailnet ? [var.tailnet_cidr] : var.allowed_api_ips } resource "hcloud_firewall" "cluster" { name = "${var.cluster_name}-firewall" rule { description = "SSH" direction = "in" protocol = "tcp" port = "22" source_ips = local.ssh_source_ips } rule { description = "Kubernetes API" direction = "in" protocol = "tcp" port = "6443" source_ips = local.api_source_ips } rule { description = "Tailscale WireGuard" direction = "in" protocol = "udp" port = "41641" source_ips = ["0.0.0.0/0"] } rule { description = "Kubernetes API (internal)" direction = "in" protocol = "tcp" port = "6443" source_ips = [var.subnet_cidr] } rule { description = "k3s Supervisor" direction = "in" protocol = "tcp" port = "9345" source_ips = [var.subnet_cidr] } rule { description = "etcd Client" direction = "in" protocol = "tcp" port = "2379" source_ips = [var.subnet_cidr] } rule { description = "etcd Peer" direction = "in" protocol = "tcp" port = "2380" source_ips = [var.subnet_cidr] } rule { description = "Flannel VXLAN" direction = "in" protocol = "udp" port = "8472" source_ips = [var.subnet_cidr] } rule { description = "Kubelet" direction = "in" protocol = "tcp" port = "10250" source_ips = [var.subnet_cidr] } dynamic "rule" { for_each = var.enable_nodeport_public ? [1] : [] content { description = "NodePorts" direction = "in" protocol = "tcp" port = "30000-32767" source_ips = ["0.0.0.0/0"] } } rule { description = "ICMP" direction = "in" protocol = "icmp" source_ips = ["0.0.0.0/0"] } apply_to { label_selector = "cluster=${var.cluster_name}" } }