2025-12-27 13:48:42 +01:00
|
|
|
# Provider Configuration
|
|
|
|
|
provider "hcloud" {
|
|
|
|
|
token = var.hcloud_token
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-05 16:40:37 +01:00
|
|
|
# hcloud provider handles both Cloud and DNS resources
|
2025-12-27 13:48:42 +01:00
|
|
|
|
2026-01-17 19:50:30 +01:00
|
|
|
# Per-Client SSH Keys
|
|
|
|
|
resource "hcloud_ssh_key" "client" {
|
|
|
|
|
for_each = var.clients
|
|
|
|
|
name = "client-${each.key}-deploy-key"
|
|
|
|
|
public_key = file("${path.module}/../keys/ssh/${each.key}.pub")
|
2025-12-27 13:48:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Firewall Rules
|
|
|
|
|
resource "hcloud_firewall" "client_firewall" {
|
|
|
|
|
name = "client-default-firewall"
|
|
|
|
|
|
|
|
|
|
# SSH (restricted - add your management IPs here)
|
|
|
|
|
rule {
|
|
|
|
|
direction = "in"
|
|
|
|
|
protocol = "tcp"
|
|
|
|
|
port = "22"
|
|
|
|
|
source_ips = [
|
|
|
|
|
"0.0.0.0/0", # CHANGE THIS: Replace with your management IP
|
|
|
|
|
"::/0"
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# HTTP (for Let's Encrypt challenge)
|
|
|
|
|
rule {
|
|
|
|
|
direction = "in"
|
|
|
|
|
protocol = "tcp"
|
|
|
|
|
port = "80"
|
|
|
|
|
source_ips = [
|
|
|
|
|
"0.0.0.0/0",
|
|
|
|
|
"::/0"
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# HTTPS
|
|
|
|
|
rule {
|
|
|
|
|
direction = "in"
|
|
|
|
|
protocol = "tcp"
|
|
|
|
|
port = "443"
|
|
|
|
|
source_ips = [
|
|
|
|
|
"0.0.0.0/0",
|
|
|
|
|
"::/0"
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Client VPS Instances
|
|
|
|
|
resource "hcloud_server" "client" {
|
|
|
|
|
for_each = var.clients
|
|
|
|
|
|
|
|
|
|
name = each.key
|
|
|
|
|
server_type = each.value.server_type
|
|
|
|
|
image = "ubuntu-24.04"
|
|
|
|
|
location = each.value.location
|
2026-01-17 19:50:30 +01:00
|
|
|
ssh_keys = [hcloud_ssh_key.client[each.key].id]
|
2025-12-27 13:48:42 +01:00
|
|
|
firewall_ids = [hcloud_firewall.client_firewall.id]
|
|
|
|
|
|
|
|
|
|
labels = {
|
|
|
|
|
client = each.key
|
|
|
|
|
role = "app-server"
|
|
|
|
|
# Note: labels can't contain special chars, store apps list separately if needed
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Enable backups if requested
|
|
|
|
|
backups = var.enable_snapshots
|
|
|
|
|
|
chore: Post-workshop state - January 23rd, 2026
This commit captures the infrastructure state immediately following
the "Post-Tyranny Tech" workshop on January 23rd, 2026.
Infrastructure Status:
- 13 client servers deployed (white, valk, zwaan, specht, das, uil, vos,
haas, wolf, ree, mees, mus, mol, kikker)
- Services: Authentik SSO, Nextcloud, Collabora Office, Traefik
- Private network architecture with edge NAT gateway
- OIDC integration between Authentik and Nextcloud
- Automated recovery flows and invitation system
- Container update monitoring with Diun
- Uptime monitoring with Uptime Kuma
Changes include:
- Multiple new client host configurations
- Network architecture improvements (private IPs + NAT)
- DNS management automation
- Container update notifications
- Email configuration via Mailgun
- SSH key generation for all clients
- Encrypted secrets for all deployments
- Health check and diagnostic scripts
Known Issues to Address:
- Nextcloud version pinned to v30 (should use 'latest' or v32)
- Zitadel references in templates (migrated to Authentik but templates not updated)
- Traefik dynamic config has obsolete static routes
🤖 Generated with Claude Code (https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-23 20:36:31 +01:00
|
|
|
# Public network configuration - all servers now have public IPs
|
2026-01-20 19:06:19 +01:00
|
|
|
public_net {
|
chore: Post-workshop state - January 23rd, 2026
This commit captures the infrastructure state immediately following
the "Post-Tyranny Tech" workshop on January 23rd, 2026.
Infrastructure Status:
- 13 client servers deployed (white, valk, zwaan, specht, das, uil, vos,
haas, wolf, ree, mees, mus, mol, kikker)
- Services: Authentik SSO, Nextcloud, Collabora Office, Traefik
- Private network architecture with edge NAT gateway
- OIDC integration between Authentik and Nextcloud
- Automated recovery flows and invitation system
- Container update monitoring with Diun
- Uptime monitoring with Uptime Kuma
Changes include:
- Multiple new client host configurations
- Network architecture improvements (private IPs + NAT)
- DNS management automation
- Container update notifications
- Email configuration via Mailgun
- SSH key generation for all clients
- Encrypted secrets for all deployments
- Health check and diagnostic scripts
Known Issues to Address:
- Nextcloud version pinned to v30 (should use 'latest' or v32)
- Zitadel references in templates (migrated to Authentik but templates not updated)
- Traefik dynamic config has obsolete static routes
🤖 Generated with Claude Code (https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-23 20:36:31 +01:00
|
|
|
ipv4_enabled = true
|
|
|
|
|
ipv6_enabled = true
|
2026-01-20 19:06:19 +01:00
|
|
|
}
|
|
|
|
|
|
2025-12-27 13:48:42 +01:00
|
|
|
# User data for initial setup
|
chore: Post-workshop state - January 23rd, 2026
This commit captures the infrastructure state immediately following
the "Post-Tyranny Tech" workshop on January 23rd, 2026.
Infrastructure Status:
- 13 client servers deployed (white, valk, zwaan, specht, das, uil, vos,
haas, wolf, ree, mees, mus, mol, kikker)
- Services: Authentik SSO, Nextcloud, Collabora Office, Traefik
- Private network architecture with edge NAT gateway
- OIDC integration between Authentik and Nextcloud
- Automated recovery flows and invitation system
- Container update monitoring with Diun
- Uptime monitoring with Uptime Kuma
Changes include:
- Multiple new client host configurations
- Network architecture improvements (private IPs + NAT)
- DNS management automation
- Container update notifications
- Email configuration via Mailgun
- SSH key generation for all clients
- Encrypted secrets for all deployments
- Health check and diagnostic scripts
Known Issues to Address:
- Nextcloud version pinned to v30 (should use 'latest' or v32)
- Zitadel references in templates (migrated to Authentik but templates not updated)
- Traefik dynamic config has obsolete static routes
🤖 Generated with Claude Code (https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-23 20:36:31 +01:00
|
|
|
user_data = templatefile("${path.module}/user-data-public.yml", {
|
2026-01-20 19:06:19 +01:00
|
|
|
hostname = each.key
|
|
|
|
|
})
|
2025-12-27 13:48:42 +01:00
|
|
|
}
|