From b10724b6b67a26de841f5e187d9dcb3112c982c1 Mon Sep 17 00:00:00 2001 From: Jim Martens Date: Sat, 7 Feb 2026 16:29:09 +0100 Subject: [PATCH] change: Manage DNS records with Hetzner ci: Update provider plugins change: Remove domains of services no longer running --- terraform/.terraform.lock.hcl | 33 ++++----- terraform/imports.tf | 74 +++++++++++++++++++ .../modules/docker-network/load-balancer.tf | 26 +++++++ terraform/modules/docker-network/main.tf | 1 + .../docker-network/swarm-manager-node.tf | 26 +++++++ terraform/modules/docker-network/versions.tf | 2 +- terraform/modules/domain/main.tf | 73 +++++++++++------- terraform/modules/domain/variables.tf | 8 +- terraform/modules/domain/versions.tf | 6 +- terraform/nameserver-records.tf | 9 +++ terraform/uberspace.tf | 61 ++++++++------- terraform/versions.tf | 2 +- 12 files changed, 235 insertions(+), 86 deletions(-) create mode 100644 terraform/nameserver-records.tf diff --git a/terraform/.terraform.lock.hcl b/terraform/.terraform.lock.hcl index 5933c67..bfef954 100644 --- a/terraform/.terraform.lock.hcl +++ b/terraform/.terraform.lock.hcl @@ -2,24 +2,23 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hetznercloud/hcloud" { - version = "1.44.1" - constraints = "1.44.1" + version = "1.60.0" + constraints = ">= 1.44.1" hashes = [ - "h1:q2JvvbG+seeZ4A2ijxPi5Tis+NJVoB59cAt3KeQe0uA=", - "zh:156df81d2c740608b9fb7f439defbb39b89585c55dc6e62e4af928808ff67f9e", - "zh:32407f1df8b59afe5e35710c4acf2c8a8cbf5ea9a32126f34cb0c49ff142a047", - "zh:456133e16e9ebfcd89534c968a8b2a3f931bf4acb76a8165acc2242b0b73ba78", - "zh:6855c90399abc11e32fcdc0bf54bdedb50009c46183b926b3493fdcf48d5e39c", - "zh:68fe1e7e9f692a29d75a3cc199b472e8bc00c9486b299bfaf816133797207804", - "zh:6c62a9fe0a6de3cd4ea0591193baef00b65c838610feb369d14e36d15f9ea93e", - "zh:6cb1db2287cc8baec8538d9df6a44f602f61580d8df4c484625295aa622f03d1", - "zh:7fd577a8079da2f6e96066a8bf6bce6e36fdd36c67ac03044fd29f15eb718a6c", - "zh:9f94d862b827c429bf6a3eea7a65b856475cdc6da7e0d8a8edfbc09de40bed3f", - "zh:a6499d633a63668629a32628624137d2ef8e1ca5ef77766669470def7f4d5732", - "zh:b46004de824350b1b9a44cc253608d25e7cdf77d628571ece2df2fe96aacb8d7", - "zh:b9d8c401f8ddb829ee67bf429aac781bf5022605f4d18b041c417622746a37a1", - "zh:cf182e8426d7bd555a46ea4c5d75ed431edb41aa162e57f07f13d235d0e74f0d", - "zh:e1b777a95498489aa04231b7825cca445119f2b1988bfdcd8f0a35e0ba59d883", + "h1:a+0jnJt73mpSsncc36Idxy5ziS7N4Iim4otcW11XkXo=", + "zh:13d729f4859bdcf9e6c2e706bdb010d1e770d8e06834335a1ef7f982fffd0c99", + "zh:3b36a77cf1869a9abce3a45e2c796cb4f3e5e819497919a8a837badbb9576a1d", + "zh:4ec1f0d4e7fe4dffd7a4a2c5846d45243b1ade669c234a772631824c1d4faa10", + "zh:5042482e86618efd1122e398faf09ccdf2ba849b0aefa589b6da656b847402d5", + "zh:52d4524bdde5424cf2a8b130ab085c1236c694da16adae9d31c925c26bbde02d", + "zh:54af898bdbbb0e342b9a2bf39725114cff52713a03ee966bd734a6a2fef953b9", + "zh:59979a5377245ffd5c962123547703bca9201a7019c6ef5ba9cf2e6119b4911d", + "zh:6006e47336182ab68c18980d620d9dc4aab8bdb250744e4c9117d694bf01192a", + "zh:8061ace3e91510afde141d3556be50b1b23b2578ec0626843641fea8dad3bcaf", + "zh:c24f6fcf0ddbe5395c71ccbda2588196b00c0090017a84d7ae4b0132197dfcd2", + "zh:ca9143d179a3815d49e61f70cc8a3340abac44e8f75259f1107520e407252923", + "zh:d5ea79ba8b22db4cb6404334316a2c58a9b7b44e8eb2ddf7d62350d99c1831d5", + "zh:eb15f600011e7822b526b137fc5e88db15a7ef7c826ebaa16fa6486cf1f1ce2a", ] } diff --git a/terraform/imports.tf b/terraform/imports.tf index e69de29..94a20f1 100644 --- a/terraform/imports.tf +++ b/terraform/imports.tf @@ -0,0 +1,74 @@ +import { + to = hcloud_zone.twomartens_de + id = "2martens.de" +} + +import { + to = module.keycloak_domain.hcloud_zone_rrset.a + id = "2martens.de/id/A" +} + +import { + to = module.keycloak_domain.hcloud_zone_rrset.aaaa + id = "2martens.de/id/AAAA" +} + +import { + to = module.keycloak_domain.hcloud_zone_rrset.mx[0] + id = "2martens.de/id/MX" +} + +import { + to = module.keycloak_domain.hcloud_zone_rrset.txt[0] + id = "2martens.de/id/TXT" +} + +import { + to = module.gitea_domain.hcloud_zone_rrset.a + id = "2martens.de/git/A" +} + +import { + to = module.gitea_domain.hcloud_zone_rrset.aaaa + id = "2martens.de/git/AAAA" +} + +import { + to = module.helm-repo_domain.hcloud_zone_rrset.a + id = "2martens.de/repo/A" +} + +import { + to = module.helm-repo_domain.hcloud_zone_rrset.aaaa + id = "2martens.de/repo/AAAA" +} + +import { + to = module.statping_domain.hcloud_zone_rrset.a + id = "2martens.de/status/A" +} + +import { + to = module.statping_domain.hcloud_zone_rrset.aaaa + id = "2martens.de/status/AAAA" +} + +import { + to = module.personal_website_domain.hcloud_zone_rrset.a + id = "2martens.de/@/A" +} + +import { + to = module.personal_website_domain.hcloud_zone_rrset.aaaa + id = "2martens.de/@/AAAA" +} + +import { + to = module.personal_website_domain.hcloud_zone_rrset.mx[0] + id = "2martens.de/@/MX" +} + +import { + to = module.personal_website_domain.hcloud_zone_rrset.txt[0] + id = "2martens.de/@/TXT" +} \ No newline at end of file diff --git a/terraform/modules/docker-network/load-balancer.tf b/terraform/modules/docker-network/load-balancer.tf index f23ac88..a37beb1 100644 --- a/terraform/modules/docker-network/load-balancer.tf +++ b/terraform/modules/docker-network/load-balancer.tf @@ -15,6 +15,32 @@ resource "hcloud_load_balancer" "docker" { } } +resource "hcloud_zone_rrset" "a_load_balancer" { + count = var.number_nodes > 1 ? 1 : 0 + + zone = var.domain + name = local.docker_subdomain + type = "A" + ttl = 3600 + + records = [ + { value = hcloud_load_balancer.docker[count.index].ipv4 } + ] +} + +resource "hcloud_zone_rrset" "aaaa_load_balancer" { + count = var.number_nodes > 1 ? 1 : 0 + + zone = var.domain + name = local.docker_subdomain + type = "AAAA" + ttl = 3600 + + records = [ + { value = hcloud_load_balancer.docker[count.index].ipv6 } + ] +} + resource "hcloud_rdns" "ipv4_load_balancer" { count = var.number_nodes > 1 ? 1 : 0 diff --git a/terraform/modules/docker-network/main.tf b/terraform/modules/docker-network/main.tf index 389cb7a..3d99e5d 100644 --- a/terraform/modules/docker-network/main.tf +++ b/terraform/modules/docker-network/main.tf @@ -4,4 +4,5 @@ data "hcloud_placement_group" "default" { locals { docker_network_domain = format("%s.%s.%s", "docker", var.stage_name, var.domain) + docker_subdomain = format("%s.%s", "docker", var.stage_name) } diff --git a/terraform/modules/docker-network/swarm-manager-node.tf b/terraform/modules/docker-network/swarm-manager-node.tf index 492933c..cff6a28 100644 --- a/terraform/modules/docker-network/swarm-manager-node.tf +++ b/terraform/modules/docker-network/swarm-manager-node.tf @@ -34,6 +34,32 @@ resource "hcloud_rdns" "ipv6_node" { dns_ptr = format("%s-%d.%s", "node", count.index, local.docker_network_domain) } +resource "hcloud_zone_rrset" "a" { + count = var.number_nodes + + zone = var.domain + name = format("%s-%d.%s", "node", count.index, local.docker_subdomain) + type = "A" + ttl = 3600 + + records = [ + { value = hcloud_primary_ip.ipv4_node_address[count.index].ip_address } + ] +} + +resource "hcloud_zone_rrset" "aaaa" { + count = var.number_nodes + + zone = var.domain + name = format("%s-%d.%s", "node", count.index, local.docker_subdomain) + type = "AAAA" + ttl = 3600 + + records = [ + { value = hcloud_primary_ip.ipv6_node_address[count.index].ip_address } + ] +} + resource "hcloud_server_network" "nginx_private" { count = var.number_nodes diff --git a/terraform/modules/docker-network/versions.tf b/terraform/modules/docker-network/versions.tf index f529ec3..afabb6a 100644 --- a/terraform/modules/docker-network/versions.tf +++ b/terraform/modules/docker-network/versions.tf @@ -2,7 +2,7 @@ terraform { required_providers { hcloud = { source = "hetznercloud/hcloud" - version = "1.44.1" + version = ">= 1.44.1" } } } diff --git a/terraform/modules/domain/main.tf b/terraform/modules/domain/main.tf index b841ebe..660131a 100644 --- a/terraform/modules/domain/main.tf +++ b/terraform/modules/domain/main.tf @@ -1,31 +1,48 @@ -resource "inwx_nameserver_record" "a" { - domain = var.domain - name = var.subdomain != "" ? format("%s.%s", var.subdomain, var.domain) : var.domain - content = var.ipv4 - type = "A" - ttl = 3600 +resource "hcloud_zone_rrset" "a" { + zone = var.domain + name = var.subdomain != "" ? var.subdomain : "@" + type = "A" + ttl = 3600 + + records = [ + { value = var.ipv4 } + ] } -resource "inwx_nameserver_record" "aaaa" { - domain = var.domain - name = var.subdomain != "" ? format("%s.%s", var.subdomain, var.domain) : var.domain - content = var.ipv6 - type = "AAAA" - ttl = 3600 + +resource "hcloud_zone_rrset" "aaaa" { + zone = var.domain + name = var.subdomain != "" ? var.subdomain : "@" + type = "AAAA" + ttl = 3600 + + records = [ + { value = var.ipv6 } + ] } -resource "inwx_nameserver_record" "mx" { - domain = var.domain - name = var.subdomain != "" ? format("%s.%s", var.subdomain, var.domain) : var.domain - content = var.hostName - type = "MX" - prio = var.mxPrio - ttl = 3600 - count = var.hasMXRecord ? 1 : 0 + +resource "hcloud_zone_rrset" "mx" { + count = var.hasMXRecord ? 1 : 0 + + zone = var.domain + name = var.subdomain != "" ? var.subdomain : "@" + type = "MX" + ttl = 3600 + + records = [ + { value = format("%s %s.", var.mxPrio, var.hostName) } + ] +} + +resource "hcloud_zone_rrset" "txt" { + count = length(var.txtValues) > 0 ? 1 : 0 + + zone = var.domain + name = var.subdomain != "" ? var.subdomain : "@" + type = "TXT" + ttl = 3600 + + records = [ + for txtValue in var.txtValues: + { value = provider::hcloud::txt_record(txtValue) } + ] } -resource "inwx_nameserver_record" "mx-spf" { - domain = var.domain - name = var.subdomain != "" ? format("%s.%s", var.subdomain, var.domain) : var.domain - content = var.mxSpf - type = "TXT" - ttl = 3600 - count = var.hasMXRecord ? 1 : 0 -} \ No newline at end of file diff --git a/terraform/modules/domain/variables.tf b/terraform/modules/domain/variables.tf index e2bf774..9d786bf 100644 --- a/terraform/modules/domain/variables.tf +++ b/terraform/modules/domain/variables.tf @@ -29,7 +29,7 @@ variable "mxPrio" { default = 0 } -variable "mxSpf" { - type = string - default = "" -} \ No newline at end of file +variable "txtValues" { + type = list(string) + default = [] +} diff --git a/terraform/modules/domain/versions.tf b/terraform/modules/domain/versions.tf index 9afa334..a52f718 100644 --- a/terraform/modules/domain/versions.tf +++ b/terraform/modules/domain/versions.tf @@ -1,8 +1,8 @@ terraform { required_providers { - inwx = { - source = "inwx/inwx" - version = ">= 1.0.0" + hcloud = { + source = "hetznercloud/hcloud" + version = ">= 1.44.1" } } } diff --git a/terraform/nameserver-records.tf b/terraform/nameserver-records.tf new file mode 100644 index 0000000..fb4870c --- /dev/null +++ b/terraform/nameserver-records.tf @@ -0,0 +1,9 @@ +resource "hcloud_zone" "twomartens_de" { + name = "2martens.de" + mode = "primary" + + ttl = 86400 + + delete_protection = true +} + diff --git a/terraform/uberspace.tf b/terraform/uberspace.tf index c635aa8..b6d9080 100644 --- a/terraform/uberspace.tf +++ b/terraform/uberspace.tf @@ -1,29 +1,29 @@ // Identity management module "keycloak_domain" { source = "./modules/domain" - domain = local.domain + domain = hcloud_zone.twomartens_de.name subdomain = "id" ipv4 = "95.143.172.184" ipv6 = "2001:1a50:11:0:98b3:92ff:fe3e:bba1" hasMXRecord = true hostName = "monoceres.uberspace.de" mxPrio = 0 - mxSpf = "v=spf1 include:spf.uberspace.de ~all" + txtValues = ["v=spf1 include:spf.uberspace.de ~all"] } // Angular frontends -module "wahlrecht_domain" { - source = "./modules/domain" - domain = local.domain - subdomain = "wahlrecht" - ipv4 = "185.26.156.43" - ipv6 = "2a00:d0c0:200:0:470:9fff:fe83:16bc" -} +# module "wahlrecht_domain" { +# source = "./modules/domain" +# domain = local.domain +# subdomain = "wahlrecht" +# ipv4 = "185.26.156.43" +# ipv6 = "2a00:d0c0:200:0:470:9fff:fe83:16bc" +# } // CI/CD module "gitea_domain" { source = "./modules/domain" - domain = local.domain + domain = hcloud_zone.twomartens_de.name subdomain = "git" ipv4 = "185.26.156.91" ipv6 = "2a00:d0c0:200:0:b9:1a:9c:5a" @@ -31,7 +31,7 @@ module "gitea_domain" { module "helm-repo_domain" { source = "./modules/domain" - domain = local.domain + domain = hcloud_zone.twomartens_de.name subdomain = "repo" ipv4 = "185.26.156.49" ipv6 = "2a00:d0c0:200:0:2ca6:bff:fe78:832f" @@ -40,7 +40,7 @@ module "helm-repo_domain" { // Monitoring module "statping_domain" { source = "./modules/domain" - domain = local.domain + domain = hcloud_zone.twomartens_de.name subdomain = "status" ipv4 = "185.26.156.33" ipv6 = "2a00:d0c0:200:0:f8e2:6fff:fec2:7a92" @@ -49,32 +49,29 @@ module "statping_domain" { // Personal Website module "personal_website_domain" { source = "./modules/domain" - domain = local.domain + domain = hcloud_zone.twomartens_de.name subdomain = "" ipv4 = "185.26.156.65" ipv6 = "2a00:d0c0:200:0:b9:1a:9c:40" hasMXRecord = true hostName = "howell.uberspace.de" mxPrio = 0 - mxSpf = "v=spf1 include:spf.uberspace.de ~all" -} -resource "inwx_nameserver_record" "twomartens_de_google-verification_txt" { - domain = local.domain - name = local.domain - content = "google-site-verification=nUFiHQFxBpBMdX96ELH3TcfyIfXf2ZlwMFYtXjVq5lo" - type = "TXT" - ttl = 3600 + txtValues = [ + "openai-domain-verification=dv-EcR0SCNAnUYVquVZVgb21Wdt", + "google-site-verification=nUFiHQFxBpBMdX96ELH3TcfyIfXf2ZlwMFYtXjVq5lo", + "v=spf1 include:spf.uberspace.de ~all" + ] } // Nextcloud -module "nextcloud_domain" { - source = "./modules/domain" - domain = local.domain - subdomain = "cloud" - ipv4 = "185.26.156.194" - ipv6 = "2a00:d0c0:200:0:b9:1a:9c:95" - hasMXRecord = true - hostName = "kushida.uberspace.de" - mxPrio = 0 - mxSpf = "v=spf1 include:spf.uberspace.de ~all" -} \ No newline at end of file +# module "nextcloud_domain" { +# source = "./modules/domain" +# domain = local.domain +# subdomain = "cloud" +# ipv4 = "185.26.156.194" +# ipv6 = "2a00:d0c0:200:0:b9:1a:9c:95" +# hasMXRecord = true +# hostName = "kushida.uberspace.de" +# mxPrio = 0 +# mxSpf = "v=spf1 include:spf.uberspace.de ~all" +# } diff --git a/terraform/versions.tf b/terraform/versions.tf index 5f7d80a..3d22849 100644 --- a/terraform/versions.tf +++ b/terraform/versions.tf @@ -13,7 +13,7 @@ terraform { } hcloud = { source = "hetznercloud/hcloud" - version = "1.44.1" + version = ">= 1.44.1" } keycloak = { source = "keycloak/keycloak"