yep, more dotfiles

describe hetzner configuration with terraform

wiro.world 118b1435 044cd08f

verified
+655
+2
shells.nix
··· 18 18 nix-inspect 19 19 nixos-anywhere 20 20 nix-tree 21 + opentofu 22 + tofu-ls 21 23 ] 22 24 ); 23 25
+4
terraform/.gitignore
··· 1 + .terraform/ 2 + *.tfstate 3 + *.tfstate.* 4 + *.tfvars
+23
terraform/.terraform.lock.hcl
··· 1 + # This file is maintained automatically by "tofu init". 2 + # Manual edits may be lost in future updates. 3 + 4 + provider "registry.opentofu.org/hetznercloud/hcloud" { 5 + version = "1.60.1" 6 + constraints = "~> 1.0" 7 + hashes = [ 8 + "h1:aFTtCV6KIyK8QpkQrJZfAyjx+GXNVaBm4qN3Vvqmwlc=", 9 + "zh:0a746671e3f149b998a2abf730a5401a07305c67f93d5bbfdcf60aa19fdebb4d", 10 + "zh:156273b900a006253841727387671dd67c7c5c502998d6a9af5a5abbf5717fdf", 11 + "zh:2daa1290c50c081bb6a6cfa76b2872ea9fd9658eb3f2e81deab58b1ee48cf348", 12 + "zh:36d6dac96ac6389f35bb1f19f40c4263bf78fa36fa7468971cf646c69eeae663", 13 + "zh:5d0040a11470ced3eddf7d3e8e823982f80f8eb127cf285cd351bfc26a4d1108", 14 + "zh:60ac7d3d948d7280a6e53088d5c41c444712f05e4274e37b0f4a81da9dcd1edb", 15 + "zh:9fe5dd114ebb6f8da0dc9b5485c42d01cd41ed61a6fe2fc92bb3038fe4d708ea", 16 + "zh:ae755ea4faca6ee410a397702a2c74f10ea28ec1ab95e1656be7a6f5908d1d23", 17 + "zh:b3edcf6ea0f6498bcbdcbac8ec69dfb79278c64c7ea46c3050cd361a603302b0", 18 + "zh:c6059fad0c4d2ecc3475c1767779a8e8adfcb1168101aae57ba7783510a24ae2", 19 + "zh:dfdeb297e97d5b97b04d16ded3f8ef6779fc22cbd0322a16aeff3b5feee36fe2", 20 + "zh:e38d04e7a5d0dbc3858eaa678167b6ec5e73035dae3479c7a61e6d971e58c765", 21 + "zh:fd60acd9f16b4eb7b442a557d19294a89f6a8a05f7ca57f4aa689a2a554e74bd", 22 + ] 23 + }
+23
terraform/README.md
··· 1 + # Terraform config 2 + 3 + ## Secrets 4 + 5 + Fill `secrets.auto.tfvars` with 6 + 7 + ```tfvars 8 + hcloud_token = "token" 9 + ``` 10 + 11 + ## Commands 12 + 13 + ``` 14 + tofu init 15 + ```` 16 + 17 + ``` 18 + tofu plan 19 + ``` 20 + 21 + ``` 22 + tofu apply 23 + ```
+372
terraform/dns.tf
··· 1 + resource "hcloud_zone" "wiro_world" { 2 + name = "wiro.world" 3 + mode = "primary" 4 + 5 + delete_protection = true 6 + } 7 + 8 + ## Portals 9 + 10 + resource "hcloud_zone_rrset" "wiro_world-weirdrow_portal-a" { 11 + zone = hcloud_zone.wiro_world.name 12 + name = "weird-row.portal" 13 + type = "A" 14 + records = [ 15 + { value = local.network.weird-row-server }, 16 + ] 17 + labels = { 18 + portal = "", 19 + } 20 + } 21 + resource "hcloud_zone_rrset" "wiro_world-weirdrow_portal-aaaa" { 22 + zone = hcloud_zone.wiro_world.name 23 + name = "weird-row.portal" 24 + type = "AAAA" 25 + records = [ 26 + { value = local.network.weird-row-server6 }, 27 + ] 28 + labels = { 29 + portal = "", 30 + } 31 + } 32 + 33 + ## Hosted services 34 + 35 + resource "hcloud_zone_rrset" "wiro_world-tl-a" { 36 + zone = hcloud_zone.wiro_world.name 37 + name = "@" 38 + type = "A" 39 + records = [ 40 + { value = local.network.weird-row-server }, 41 + ] 42 + } 43 + resource "hcloud_zone_rrset" "wiro_world-tl-aaaa" { 44 + zone = hcloud_zone.wiro_world.name 45 + name = "@" 46 + type = "AAAA" 47 + records = [ 48 + { value = local.network.weird-row-server6 }, 49 + ] 50 + } 51 + 52 + resource "hcloud_zone_rrset" "wiro_world-knot-cname" { 53 + zone = hcloud_zone.wiro_world.name 54 + name = "knot" 55 + type = "CNAME" 56 + records = [ 57 + { value = "weird-row.portal" }, 58 + ] 59 + } 60 + resource "hcloud_zone_rrset" "wiro_world-headscale-cname" { 61 + zone = hcloud_zone.wiro_world.name 62 + name = "headscale" 63 + type = "CNAME" 64 + records = [ 65 + { value = "weird-row.portal" }, 66 + ] 67 + } 68 + resource "hcloud_zone_rrset" "wiro_world-auth-cname" { 69 + zone = hcloud_zone.wiro_world.name 70 + name = "auth" 71 + type = "CNAME" 72 + records = [ 73 + { value = "weird-row.portal" }, 74 + ] 75 + } 76 + resource "hcloud_zone_rrset" "wiro_world-matrix-cname" { 77 + zone = hcloud_zone.wiro_world.name 78 + name = "matrix" 79 + type = "CNAME" 80 + records = [ 81 + { value = "weird-row.portal" }, 82 + ] 83 + } 84 + resource "hcloud_zone_rrset" "wiro_world-news-cname" { 85 + zone = hcloud_zone.wiro_world.name 86 + name = "news" 87 + type = "CNAME" 88 + records = [ 89 + { value = "weird-row.portal" }, 90 + ] 91 + } 92 + resource "hcloud_zone_rrset" "wiro_world-spindle-cname" { 93 + zone = hcloud_zone.wiro_world.name 94 + name = "spindle" 95 + type = "CNAME" 96 + records = [ 97 + { value = "weird-row.portal" }, 98 + ] 99 + } 100 + resource "hcloud_zone_rrset" "wiro_world-stats-cname" { 101 + zone = hcloud_zone.wiro_world.name 102 + name = "stats" 103 + type = "CNAME" 104 + records = [ 105 + { value = "weird-row.portal" }, 106 + ] 107 + } 108 + resource "hcloud_zone_rrset" "wiro_world-status-cname" { 109 + zone = hcloud_zone.wiro_world.name 110 + name = "status" 111 + type = "CNAME" 112 + records = [ 113 + { value = "weird-row.portal" }, 114 + ] 115 + } 116 + resource "hcloud_zone_rrset" "wiro_world-vault-cname" { 117 + zone = hcloud_zone.wiro_world.name 118 + name = "vault" 119 + type = "CNAME" 120 + records = [ 121 + { value = "weird-row.portal" }, 122 + ] 123 + } 124 + 125 + resource "hcloud_zone_rrset" "wiro_world-pds-cname" { 126 + zone = hcloud_zone.wiro_world.name 127 + name = "pds" 128 + type = "CNAME" 129 + records = [ 130 + { value = "weird-row.portal" }, 131 + ] 132 + labels = { 133 + atproto = "", 134 + } 135 + } 136 + resource "hcloud_zone_rrset" "wiro_world-wildcard_pds-cname" { 137 + zone = hcloud_zone.wiro_world.name 138 + name = "*.pds" 139 + type = "CNAME" 140 + records = [ 141 + { value = "weird-row.portal" }, 142 + ] 143 + labels = { 144 + atproto = "", 145 + } 146 + } 147 + 148 + ## External services 149 + 150 + resource "hcloud_zone_rrset" "wiro_world-kalei-cname" { 151 + zone = hcloud_zone.wiro_world.name 152 + name = "kalei" 153 + type = "CNAME" 154 + records = [ 155 + { value = "github.io." }, 156 + ] 157 + } 158 + 159 + ## Agnos 160 + 161 + resource "hcloud_zone_rrset" "wiro_world-agnos_weirdrow_portal-aaaa" { 162 + zone = hcloud_zone.wiro_world.name 163 + name = "agnos.weird-row.portal" 164 + type = "AAAA" 165 + records = [ 166 + { value = local.network.weird-row-server6-agnos }, 167 + ] 168 + labels = { 169 + agnos = "", 170 + } 171 + } 172 + 173 + resource "hcloud_zone_rrset" "wiro_world-acme_challenge-ns" { 174 + zone = hcloud_zone.wiro_world.name 175 + name = "_acme-challenge" 176 + type = "NS" 177 + records = [ 178 + { value = "agnos.weird-row.portal" }, 179 + ] 180 + labels = { 181 + agnos = "", 182 + } 183 + } 184 + resource "hcloud_zone_rrset" "wiro_world-acme_challenge_net-ns" { 185 + zone = hcloud_zone.wiro_world.name 186 + name = "_acme-challenge.net" 187 + type = "NS" 188 + records = [ 189 + { value = "agnos.weird-row.portal" }, 190 + ] 191 + labels = { 192 + agnos = "", 193 + } 194 + } 195 + resource "hcloud_zone_rrset" "wiro_world-acme_challenge_pds-ns" { 196 + zone = hcloud_zone.wiro_world.name 197 + name = "_acme-challenge.pds" 198 + type = "NS" 199 + records = [ 200 + { value = "agnos.weird-row.portal" }, 201 + ] 202 + labels = { 203 + agnos = "", 204 + } 205 + } 206 + 207 + ## Mail 208 + 209 + resource "hcloud_zone_rrset" "wiro_world-tl-mx" { 210 + zone = hcloud_zone.wiro_world.name 211 + name = "@" 212 + type = "MX" 213 + records = [ 214 + { value = "10 aspmx1.migadu.com." }, 215 + { value = "20 aspmx2.migadu.com." }, 216 + ] 217 + labels = { 218 + mail = "", 219 + } 220 + } 221 + resource "hcloud_zone_rrset" "wiro_world-tl-txt" { 222 + zone = hcloud_zone.wiro_world.name 223 + name = "@" 224 + type = "TXT" 225 + records = [ 226 + { value = provider::hcloud::txt_record("hosted-email-verify=uxyn9qye") }, 227 + { value = provider::hcloud::txt_record("v=spf1 include:spf.migadu.com -all") }, 228 + ] 229 + labels = { 230 + mail = "", 231 + } 232 + } 233 + resource "hcloud_zone_rrset" "wiro_world-dmarc-txt" { 234 + zone = hcloud_zone.wiro_world.name 235 + name = "_dmarc" 236 + type = "TXT" 237 + records = [ 238 + { value = provider::hcloud::txt_record("v=DMARC1;p=quarantine;") }, 239 + ] 240 + labels = { 241 + mail = "", 242 + } 243 + } 244 + 245 + resource "hcloud_zone_rrset" "wiro_world-key1_domainkey-cname" { 246 + zone = hcloud_zone.wiro_world.name 247 + name = "key1._domainkey" 248 + type = "CNAME" 249 + records = [ 250 + { value = "key1.wiro.world._domainkey.migadu.com." }, 251 + ] 252 + labels = { 253 + mail = "", 254 + } 255 + } 256 + resource "hcloud_zone_rrset" "wiro_world-key2_domainkey-cname" { 257 + zone = hcloud_zone.wiro_world.name 258 + name = "key2._domainkey" 259 + type = "CNAME" 260 + records = [ 261 + { value = "key2.wiro.world._domainkey.migadu.com." }, 262 + ] 263 + labels = { 264 + mail = "", 265 + } 266 + } 267 + resource "hcloud_zone_rrset" "wiro_world-key3_domainkey-cname" { 268 + zone = hcloud_zone.wiro_world.name 269 + name = "key3._domainkey" 270 + type = "CNAME" 271 + records = [ 272 + { value = "key3.wiro.world._domainkey.migadu.com." }, 273 + ] 274 + labels = { 275 + mail = "", 276 + } 277 + } 278 + 279 + resource "hcloud_zone_rrset" "wiro_world-autoconfig-cname" { 280 + zone = hcloud_zone.wiro_world.name 281 + name = "autoconfig" 282 + type = "CNAME" 283 + records = [ 284 + { value = "autoconfig.migadu.com." }, 285 + ] 286 + labels = { 287 + mail = "", 288 + } 289 + } 290 + resource "hcloud_zone_rrset" "wiro_world-imaps_tcp-srv" { 291 + zone = hcloud_zone.wiro_world.name 292 + name = "_imaps._tcp" 293 + type = "SRV" 294 + records = [ 295 + { value = "0 1 993 imap.migadu.com" }, 296 + ] 297 + labels = { 298 + mail = "", 299 + } 300 + } 301 + resource "hcloud_zone_rrset" "wiro_world-submissions_tcp-srv" { 302 + zone = hcloud_zone.wiro_world.name 303 + name = "_submissions._tcp" 304 + type = "SRV" 305 + records = [ 306 + { value = "0 1 465 smtp.migadu.com" }, 307 + ] 308 + labels = { 309 + mail = "", 310 + } 311 + } 312 + 313 + resource "hcloud_zone_rrset" "wiro_world-send_services-mx" { 314 + zone = hcloud_zone.wiro_world.name 315 + name = "send.services" 316 + type = "MX" 317 + records = [ 318 + { value = "10 feedback-smtp.eu-west-1.amazonses.com." }, 319 + ] 320 + labels = { 321 + mail = "", 322 + } 323 + } 324 + resource "hcloud_zone_rrset" "wiro_world-send_services-txt" { 325 + zone = hcloud_zone.wiro_world.name 326 + name = "send.services" 327 + type = "TXT" 328 + records = [ 329 + { value = provider::hcloud::txt_record("v=spf1 include:amazonses.com ~all") }, 330 + ] 331 + labels = { 332 + mail = "", 333 + } 334 + } 335 + resource "hcloud_zone_rrset" "wiro_world-resend_domainkey_services-txt" { 336 + zone = hcloud_zone.wiro_world.name 337 + name = "resend._domainkey.services" 338 + type = "TXT" 339 + records = [ 340 + { value = provider::hcloud::txt_record("p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRtv2LsjWWf6UjdtD9Ri8J2kmm+mWRqlnH+pY18UnbYZ/Ia8X3tLFFIda7IjQQ7iEDmkVETDPG6uxszUnMaZZZGQtN+XyY290FfoEPX1Cyi7AYHJKK40pgylynxA0KGjp5+vO/+9nxtReCYmLZIIhJ9uxHyQXCPxLfzl+Cq0uxMwIDAQAB") }, 341 + ] 342 + labels = { 343 + mail = "", 344 + } 345 + } 346 + 347 + ## Identification 348 + 349 + resource "hcloud_zone_rrset" "wiro_world-atproto-txt" { 350 + zone = hcloud_zone.wiro_world.name 351 + name = "_atproto" 352 + type = "TXT" 353 + records = [ 354 + { value = provider::hcloud::txt_record("did=did:plc:xhgrjm4mcx3p5h3y6eino6ti") }, 355 + ] 356 + labels = { 357 + atproto = "", 358 + } 359 + } 360 + 361 + ## Reverse DNS 362 + 363 + resource "hcloud_rdns" "primary-v4" { 364 + primary_ip_id = hcloud_primary_ip.primary-v4.id 365 + ip_address = hcloud_primary_ip.primary-v4.ip_address 366 + dns_ptr = "weird-row.portal.wiro.world" 367 + } 368 + resource "hcloud_rdns" "primary-v6" { 369 + primary_ip_id = hcloud_primary_ip.primary-v6.id 370 + ip_address = cidrhost(hcloud_primary_ip.primary-v6.ip_network, 1) 371 + dns_ptr = "weird-row.portal.wiro.world" 372 + }
+48
terraform/main.tf
··· 1 + terraform { 2 + required_providers { 3 + hcloud = { 4 + source = "hetznercloud/hcloud" 5 + version = "~> 1" 6 + } 7 + } 8 + } 9 + 10 + provider "hcloud" { 11 + token = var.hcloud_token 12 + } 13 + 14 + variable "hcloud_token" { 15 + sensitive = true 16 + } 17 + 18 + resource "hcloud_primary_ip" "primary-v4" { 19 + name = "primary-v4" 20 + location = "nbg1" 21 + type = "ipv4" 22 + 23 + assignee_type = "server" 24 + auto_delete = false 25 + delete_protection = true 26 + } 27 + 28 + resource "hcloud_primary_ip" "primary-v6" { 29 + name = "primary-v6" 30 + location = "nbg1" 31 + type = "ipv6" 32 + 33 + assignee_type = "server" 34 + auto_delete = false 35 + delete_protection = true 36 + } 37 + 38 + locals { 39 + network = { 40 + weird-row-server = hcloud_primary_ip.primary-v4.ip_address 41 + weird-row-server6 = cidrhost(hcloud_primary_ip.primary-v6.ip_network, 1) 42 + weird-row-server6-agnos = cidrhost(hcloud_primary_ip.primary-v6.ip_network, 2) 43 + } 44 + } 45 + 46 + output "network" { 47 + value = local.network 48 + }
+167
terraform/mappings.tf
··· 1 + ## Servers 2 + 3 + import { 4 + to = hcloud_server.weird-row-server 5 + id = "62287388" 6 + } 7 + 8 + ## Networks 9 + 10 + import { 11 + to = hcloud_primary_ip.primary-v4 12 + id = "85834839" 13 + } 14 + import { 15 + to = hcloud_primary_ip.primary-v6 16 + id = "85776061" 17 + } 18 + 19 + ## DNS 20 + 21 + import { 22 + to = hcloud_zone.wiro_world 23 + id = "50469" 24 + } 25 + import { 26 + to = hcloud_zone_rrset.wiro_world-weirdrow_portal-a 27 + id = "wiro.world/weird-row.portal/A" 28 + } 29 + import { 30 + to = hcloud_zone_rrset.wiro_world-weirdrow_portal-aaaa 31 + id = "wiro.world/weird-row.portal/AAAA" 32 + } 33 + import { 34 + to = hcloud_zone_rrset.wiro_world-tl-a 35 + id = "wiro.world/@/A" 36 + } 37 + import { 38 + to = hcloud_zone_rrset.wiro_world-tl-aaaa 39 + id = "wiro.world/@/AAAA" 40 + } 41 + import { 42 + to = hcloud_zone_rrset.wiro_world-knot-cname 43 + id = "wiro.world/knot/CNAME" 44 + } 45 + import { 46 + to = hcloud_zone_rrset.wiro_world-headscale-cname 47 + id = "wiro.world/headscale/CNAME" 48 + } 49 + import { 50 + to = hcloud_zone_rrset.wiro_world-auth-cname 51 + id = "wiro.world/auth/CNAME" 52 + } 53 + import { 54 + to = hcloud_zone_rrset.wiro_world-matrix-cname 55 + id = "wiro.world/matrix/CNAME" 56 + } 57 + import { 58 + to = hcloud_zone_rrset.wiro_world-news-cname 59 + id = "wiro.world/news/CNAME" 60 + } 61 + import { 62 + to = hcloud_zone_rrset.wiro_world-spindle-cname 63 + id = "wiro.world/spindle/CNAME" 64 + } 65 + import { 66 + to = hcloud_zone_rrset.wiro_world-stats-cname 67 + id = "wiro.world/stats/CNAME" 68 + } 69 + import { 70 + to = hcloud_zone_rrset.wiro_world-status-cname 71 + id = "wiro.world/status/CNAME" 72 + } 73 + import { 74 + to = hcloud_zone_rrset.wiro_world-vault-cname 75 + id = "wiro.world/vault/CNAME" 76 + } 77 + import { 78 + to = hcloud_zone_rrset.wiro_world-pds-cname 79 + id = "wiro.world/pds/CNAME" 80 + } 81 + import { 82 + to = hcloud_zone_rrset.wiro_world-wildcard_pds-cname 83 + id = "wiro.world/*.pds/CNAME" 84 + } 85 + import { 86 + to = hcloud_zone_rrset.wiro_world-kalei-cname 87 + id = "wiro.world/kalei/CNAME" 88 + } 89 + import { 90 + to = hcloud_zone_rrset.wiro_world-agnos_weirdrow_portal-aaaa 91 + id = "wiro.world/agnos.weird-row.portal/AAAA" 92 + } 93 + import { 94 + to = hcloud_zone_rrset.wiro_world-acme_challenge-ns 95 + id = "wiro.world/_acme-challenge/NS" 96 + } 97 + import { 98 + to = hcloud_zone_rrset.wiro_world-acme_challenge_net-ns 99 + id = "wiro.world/_acme-challenge.net/NS" 100 + } 101 + import { 102 + to = hcloud_zone_rrset.wiro_world-acme_challenge_pds-ns 103 + id = "wiro.world/_acme-challenge.pds/NS" 104 + } 105 + import { 106 + to = hcloud_zone_rrset.wiro_world-tl-mx 107 + id = "wiro.world/@/MX" 108 + } 109 + import { 110 + to = hcloud_zone_rrset.wiro_world-tl-txt 111 + id = "wiro.world/@/TXT" 112 + } 113 + import { 114 + to = hcloud_zone_rrset.wiro_world-dmarc-txt 115 + id = "wiro.world/_dmarc/TXT" 116 + } 117 + import { 118 + to = hcloud_zone_rrset.wiro_world-key1_domainkey-cname 119 + id = "wiro.world/key1._domainkey/CNAME" 120 + } 121 + import { 122 + to = hcloud_zone_rrset.wiro_world-key2_domainkey-cname 123 + id = "wiro.world/key2._domainkey/CNAME" 124 + } 125 + import { 126 + to = hcloud_zone_rrset.wiro_world-key3_domainkey-cname 127 + id = "wiro.world/key3._domainkey/CNAME" 128 + } 129 + import { 130 + to = hcloud_zone_rrset.wiro_world-autoconfig-cname 131 + id = "wiro.world/autoconfig/CNAME" 132 + } 133 + import { 134 + to = hcloud_zone_rrset.wiro_world-imaps_tcp-srv 135 + id = "wiro.world/_imaps._tcp/SRV" 136 + } 137 + import { 138 + to = hcloud_zone_rrset.wiro_world-submissions_tcp-srv 139 + id = "wiro.world/_submissions._tcp/SRV" 140 + } 141 + import { 142 + to = hcloud_zone_rrset.wiro_world-send_services-mx 143 + id = "wiro.world/send.services/MX" 144 + } 145 + import { 146 + to = hcloud_zone_rrset.wiro_world-send_services-txt 147 + id = "wiro.world/send.services/TXT" 148 + } 149 + import { 150 + to = hcloud_zone_rrset.wiro_world-resend_domainkey_services-txt 151 + id = "wiro.world/resend._domainkey.services/TXT" 152 + } 153 + import { 154 + to = hcloud_zone_rrset.wiro_world-atproto-txt 155 + id = "wiro.world/_atproto/TXT" 156 + } 157 + 158 + ## Reverse DNS 159 + 160 + import { 161 + to = hcloud_rdns.primary-v4 162 + id = "p-85834839-91.99.55.74" 163 + } 164 + import { 165 + to = hcloud_rdns.primary-v6 166 + id = "p-85776061-2a01:4f8:c2c:76d2::1" 167 + }
+16
terraform/weird-row-server.tf
··· 1 + resource "hcloud_server" "weird-row-server" { 2 + name = "weird-row-server" 3 + server_type = "cx23" 4 + 5 + image = "ubuntu-20.04" 6 + location = "nbg1" 7 + backups = true 8 + 9 + public_net { 10 + ipv4 = hcloud_primary_ip.primary-v4.id 11 + ipv6 = hcloud_primary_ip.primary-v6.id 12 + } 13 + 14 + rebuild_protection = true 15 + delete_protection = true 16 + }