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}