feat: integrate tailscale access and lock SSH/API to tailnet
Some checks failed
Deploy Cluster / Terraform (push) Failing after 20s
Deploy Cluster / Ansible (push) Has been skipped

This commit is contained in:
2026-03-01 04:04:56 +00:00
parent f95dfbf9ac
commit 1eebfe77df
9 changed files with 134 additions and 23 deletions

View File

@@ -1,3 +1,8 @@
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"
@@ -6,7 +11,7 @@ resource "hcloud_firewall" "cluster" {
direction = "in"
protocol = "tcp"
port = "22"
source_ips = var.allowed_ssh_ips
source_ips = local.ssh_source_ips
}
rule {
@@ -14,7 +19,15 @@ resource "hcloud_firewall" "cluster" {
direction = "in"
protocol = "tcp"
port = "6443"
source_ips = var.allowed_api_ips
source_ips = local.api_source_ips
}
rule {
description = "Tailscale WireGuard"
direction = "in"
protocol = "udp"
port = "41641"
source_ips = ["0.0.0.0/0"]
}
rule {
@@ -65,12 +78,15 @@ resource "hcloud_firewall" "cluster" {
source_ips = [var.subnet_cidr]
}
rule {
description = "NodePorts"
direction = "in"
protocol = "tcp"
port = "30000-32767"
source_ips = ["0.0.0.0/0"]
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 {

View File

@@ -3,6 +3,11 @@ output "control_plane_ips" {
value = [for cp in hcloud_server.control_plane : cp.ipv4_address]
}
output "control_plane_names" {
description = "Control plane hostnames"
value = [for cp in hcloud_server.control_plane : cp.name]
}
output "control_plane_private_ips" {
description = "Private IPs of control plane nodes"
value = [for cp in hcloud_server.control_plane : one(cp.network).ip]
@@ -18,6 +23,11 @@ output "worker_ips" {
value = [for worker in hcloud_server.workers : worker.ipv4_address]
}
output "worker_names" {
description = "Worker hostnames"
value = [for worker in hcloud_server.workers : worker.name]
}
output "worker_private_ips" {
description = "Private IPs of worker nodes"
value = [for worker in hcloud_server.workers : one(worker.network).ip]
@@ -33,6 +43,11 @@ output "cluster_name" {
value = var.cluster_name
}
output "tailscale_tailnet" {
description = "Tailnet domain suffix"
value = var.tailscale_tailnet
}
output "network_cidr" {
description = "Private network CIDR"
value = var.subnet_cidr

View File

@@ -17,6 +17,14 @@ resource "hcloud_server" "control_plane" {
role = "control-plane"
}
user_data = <<-EOF
#cloud-config
package_update: true
runcmd:
- curl -fsSL https://tailscale.com/install.sh | sh
- tailscale up --authkey '${var.tailscale_auth_key}' --hostname '${var.cluster_name}-cp-${count.index + 1}' --ssh=false --accept-routes=false
EOF
network {
network_id = hcloud_network.cluster.id
ip = cidrhost(var.subnet_cidr, 10 + count.index)
@@ -44,6 +52,14 @@ resource "hcloud_server" "workers" {
role = "worker"
}
user_data = <<-EOF
#cloud-config
package_update: true
runcmd:
- curl -fsSL https://tailscale.com/install.sh | sh
- tailscale up --authkey '${var.tailscale_auth_key}' --hostname '${var.cluster_name}-worker-${count.index + 1}' --ssh=false --accept-routes=false
EOF
network {
network_id = hcloud_network.cluster.id
ip = cidrhost(var.subnet_cidr, 20 + count.index)

View File

@@ -55,13 +55,42 @@ variable "location" {
variable "allowed_ssh_ips" {
description = "IP ranges allowed for SSH access"
type = list(string)
default = ["0.0.0.0/0"]
default = []
}
variable "allowed_api_ips" {
description = "IP ranges allowed for Kubernetes API access"
type = list(string)
default = ["0.0.0.0/0"]
default = []
}
variable "restrict_api_ssh_to_tailnet" {
description = "Restrict SSH and Kubernetes API to tailnet CIDR"
type = bool
default = true
}
variable "tailnet_cidr" {
description = "Tailnet CIDR used for SSH/API access"
type = string
default = "100.64.0.0/10"
}
variable "tailscale_auth_key" {
description = "Tailscale auth key for node bootstrap"
type = string
sensitive = true
}
variable "tailscale_tailnet" {
description = "Tailnet domain suffix, e.g. mytailnet.ts.net"
type = string
}
variable "enable_nodeport_public" {
description = "Allow public NodePort traffic"
type = bool
default = false
}
variable "network_cidr" {