main
 1terraform {
 2  required_providers {
 3    hcloud = {
 4      source  = "hetznercloud/hcloud"
 5      version = "~> 1.49"
 6    }
 7  }
 8  required_version = ">= 1.6.0"
 9}
10
11provider "hcloud" {
12  token = var.hcloud_token
13}
14
15# SSH keys for access (kyushu for nixos-anywhere automation, homelab for interactive)
16resource "hcloud_ssh_key" "keys" {
17  for_each   = var.ssh_public_keys
18  name       = each.key
19  public_key = file(each.value)
20}
21
22# Firewall
23resource "hcloud_firewall" "carthage" {
24  name = "carthage"
25
26  # SSH — for nixos-anywhere bootstrap
27  # Restrict to VPN-only after migration is complete
28  rule {
29    direction  = "in"
30    protocol   = "tcp"
31    port       = "22"
32    source_ips = ["0.0.0.0/0", "::/0"]
33  }
34
35  # HTTP
36  rule {
37    direction  = "in"
38    protocol   = "tcp"
39    port       = "80"
40    source_ips = ["0.0.0.0/0", "::/0"]
41  }
42
43  # HTTPS
44  rule {
45    direction  = "in"
46    protocol   = "tcp"
47    port       = "443"
48    source_ips = ["0.0.0.0/0", "::/0"]
49  }
50
51  # WireGuard
52  rule {
53    direction  = "in"
54    protocol   = "udp"
55    port       = "51820"
56    source_ips = ["0.0.0.0/0", "::/0"]
57  }
58
59  # ICMP (ping)
60  rule {
61    direction  = "in"
62    protocol   = "icmp"
63    source_ips = ["0.0.0.0/0", "::/0"]
64  }
65}
66
67# The server
68resource "hcloud_server" "carthage" {
69  name        = "carthage"
70  server_type = var.server_type
71  location    = var.location
72  image       = "ubuntu-24.04" # Temporary — nixos-anywhere will overwrite
73
74  ssh_keys     = [for k in hcloud_ssh_key.keys : k.id]
75  firewall_ids = [hcloud_firewall.carthage.id]
76
77  labels = {
78    environment = "production"
79    role        = "gateway"
80    managed_by  = "opentofu"
81  }
82}