diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl
index 11361a9..1627aee 100644
--- a/.terraform.lock.hcl
+++ b/.terraform.lock.hcl
@@ -2,46 +2,52 @@
 # Manual edits may be lost in future updates.
 
 provider "registry.opentofu.org/cloudflare/cloudflare" {
-  version     = "4.40.0"
-  constraints = "4.40.0"
+  version     = "5.2.0"
+  constraints = "5.2.0"
   hashes = [
-    "h1:oWcWlZe52ZRyLQciNe94RaWzhHifSTu03nlK0uL7rlM=",
-    "h1:p3JJrhGEPlPQP7Uwy9FNMdvqCyD8tuT4lnXuJ+pSF/M=",
-    "h1:wtB0sKxG2K/H41hWJI4uJdImWquuaP34Sip5LmfE410=",
-    "zh:01742e5946f936548f8e42120287ffc757abf97e7cbbe34e25c266a438fb54fd",
-    "zh:08d81f5a5aab4cc269f983b8c6b5be0e278105136aca9681740802619577371f",
-    "zh:0d75131ba70902cfc94a7a5900369bdde56528b2aad6e10b164449cc97d57396",
-    "zh:3890a715a012e197541daacdacb8cceec6d364814daa4640ddfe98a8ba9036cb",
-    "zh:58254ce5ebe1faed4664df86210c39d660bcdc60280f17b25fe4d4dbea21ea8c",
-    "zh:6b0abc1adbc2edee79368ce9f7338ebcb5d0bf941e8d7d9ac505b750f20f80a2",
-    "zh:81cc415d1477174a1ca288d25fdb57e5ee488c2d7f61f265ef995b255a53b0ce",
-    "zh:8680140c7fe5beaefe61c5cfa471bf88422dc0c0f05dad6d3cb482d4ffd22be4",
-    "zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
-    "zh:a491d26236122ccb83dac8cb490d2c0aa1f4d3a0b4abe99300fd49b1a624f42f",
-    "zh:a70d9c469dc8d55715ba77c9d1a4ede1fdebf79e60ee18438a0844868db54e0d",
-    "zh:a7fcb7d5c4222e14ec6d9a15adf8b9a083d84b102c3d0e4a0d102df5a1360b62",
-    "zh:b4f9677174fabd199c8ebd2e9e5eb3528cf887e700569a4fb61eef4e070cec5e",
-    "zh:c27f0f7519221d75dae4a3787a59e05acd5cc9a0d30a390eff349a77d20d52e6",
-    "zh:db00d8605dbf43ca42fe1481a6c67fdcaa73debb7d2a0f613cb95ae5c5e7150e",
+    "h1:sziDJLvLyH/09VGQG51UjPSu5rW+CND6EPFQvRD2eME=",
+    "zh:1c2785da1d01b2afd0cca625e8fee472a36f681dc206823db9d59e82a4a7db68",
+    "zh:cfe874ddc069cce594f2b660bbac4692bf267012002e1884fd0772ba3ddd77ef",
+    "zh:debe086c0fee03bebebce9bf387ff3859efb54471d10981fe408de81c1af03f1",
+    "zh:e42fa5538a90620a366af7a32a48197fcb4509c6ade5ad4750166435de06fbe3",
+    "zh:e8d6eef684bbd12c6d9678a8ebeb7be982eb44f5916e1c471419dd78d3911848",
+    "zh:ea0698597ccc8a5fef56d0b76678a20701dc4f8b74e4b4c53904e3372cb50de7",
+    "zh:f809ab383cca0a5f83072981c64208cbd7fa67e986a86ee02dd2c82333221e32",
+  ]
+}
+
+provider "registry.opentofu.org/hashicorp/azurerm" {
+  version     = "4.24.0"
+  constraints = "4.24.0"
+  hashes = [
+    "h1:W59qk+rxqZeDlRrqTPgt35B8Apjt8gW467mEOfsGg/U=",
+    "zh:04f7742ceda574369ed849b33cb8b411d75e7db5b963e43467c6665e1d55eeef",
+    "zh:095b4cfdb82d2b98975831e81101448069de9928aa0eb9f5394aa1b3379046bb",
+    "zh:0afd4011a3cddd48e7f3e1fd704bd1edbc69811598b6b10f93c9687ed04c55da",
+    "zh:8856f286cdd6d9ab8ebc5b8f56a24cb61a9a5b17328820016cf93ba27f68119d",
+    "zh:8b252d38af8cb99788f3d34623043023bda06f6e4ed35b7579a53c6564c1ddbb",
+    "zh:96bcee9d350e7ad8313821cbb05aca613afb523429524135054d199e1eea0f2b",
+    "zh:a3253f8523dce7ed152137bd651b8005f6d0bb0ce46877633d4ec0d780fb6deb",
+    "zh:df656a1a43adf646a93321e89b1cb93c74fc28ec72e0b4d7967be7431d0fcc26",
+    "zh:f8411caef5f81ee626b78fabc70a9f1018a8a2753a0c6d93500fc149db64a9fe",
   ]
 }
 
 provider "registry.opentofu.org/hashicorp/cloudinit" {
-  version     = "2.3.5"
-  constraints = "2.3.5"
+  version     = "2.3.6"
+  constraints = "2.3.6"
   hashes = [
-    "h1:HU/CB76gyN3uoyFjK6YX5/KRnAmrBU9Dsm6ZOFjUBDE=",
-    "h1:ik4dUKpGZ3uDlDxKtoGTbTFdJSbVhQq7LbpmOn8PA5k=",
-    "zh:18d857ff5090bb50bc7314c11852709001ab33db1c9a957327125335ee105b0b",
-    "zh:31909baeeab00b70c871c4f310b0bbe12334ab2bda2adf4e1d51b6447f2ee6ce",
-    "zh:4ebd2975c7b0a4d142cc2002483316503087a0a4ab8947a54df8d71832e3cdee",
-    "zh:5c151543b94d1f8191257ca5e656c47f3d4524211ca60d462f8ab3f2c890e2ff",
-    "zh:67dfd1063ddfae0bcf1704c69fc17704ce4243dacdc862c9c184dcb6141ee568",
-    "zh:7f6a18a3d1dc5f2d1770516ff7f2c267ceef08071dbba485d632e04c107e9a8f",
-    "zh:993373080b67bd32a3ee6ec106dcb7891664cbbac515272af22ffd84dde68d0c",
-    "zh:a72fe5757f7456491a5e7b91dd088f993082470b6acae8cf1ed0c922c81adb18",
-    "zh:a7987554dc22fc16a2cca9b47cbed1a7d4f93c264b56bfefc819bf1a5b28e59a",
-    "zh:e1ca388d9eb2edc34ed26564004bcd2f6384f49956c757363886a535b275ac9c",
+    "h1:VgSX5Yqr00surhrA5cotpYcqUWK9WyepT7UOICyGdIs=",
+    "zh:0ad497b645e83bc82fac2fc6dbf63ff4b465dd18e9b0265b1852462e12a8cd4c",
+    "zh:10666a26ba19fdccdaf011f6b0c10ad9b80182afd1444ab28f669739a06d19a0",
+    "zh:57de6a85287c081647fdc57096c164b0f84ca36327aabaee66c425547117ac13",
+    "zh:57f7dc71c6fb22ad6b42fdcfdf8e1fa14ddb5cf0185dfd292ce73e02f050480d",
+    "zh:631ee274a22afcaa46b792f0cac56e8ea8894cbeb60f1119ae421b9c263f7b32",
+    "zh:6fd78c16cca8ec454a7c9a1b76d08617d17af5dd2bfb546e30da8940539d3aa7",
+    "zh:843f882ed06b9cb77fef3bd178b493117d7121d99c8eb36bc81e5e11b6979606",
+    "zh:a18e078db3c49264a45dfedbe99e8b3cb170fa7b8a9b253a176e9e96f1da8f9f",
+    "zh:a9aa2a5a3300254b27385c265201aece8bf1406d7229da4b4225263070a3c809",
+    "zh:b6225ae80101db018d4b372c6dc776412c45607ed859eb9bcd7e8589cc2b9393",
   ]
 }
 
@@ -101,26 +107,24 @@ provider "registry.opentofu.org/hashicorp/tls" {
 }
 
 provider "registry.opentofu.org/hetznercloud/hcloud" {
-  version     = "1.48.0"
-  constraints = "1.48.0"
+  version     = "1.50.0"
+  constraints = "1.50.0"
   hashes = [
-    "h1:pdeMfdZHftUivK+TGABJI4fnRHvF0GFbCGWxh+uL+94=",
-    "h1:sbjxzMtxkLOkhc1mbgVOmG7sCF7WZgTgRQqWPG/fld4=",
-    "h1:yQMfBy4LLbJZtQxCrXmaRuY8e2dFJAIMxJeJ9e0HlEU=",
-    "zh:19d38d046e26153edcdd36ce8c0e16198aa9dea5186559651c4a75c455390573",
-    "zh:3cb7c453067bcabed68275f812100685fc2f753f37c0e620d3358e642833b5f0",
-    "zh:42cabdbb55dba02816be8d9d3fc30f51d610516cc54c3f057e6bb3ffc960b550",
-    "zh:486aaa88c6c9af37f07ffea4b54a7dbd11e9faee09f4ed3f2dbcb2d94064427a",
-    "zh:69b1a9dc867d9beac752f42501f465ea22d3fbc8af8b3a7190b6aa50fcc0db51",
-    "zh:7422b2ec1188d9e70c3ee34ff201eb12809c0602a009224f7cea6940cce64567",
-    "zh:7e31665f004a4d0055f0b1b0c0f4d36039c11bb789fc7c07fc9fb54d0d38d751",
-    "zh:866eb35b5ca82566f7793ec88dc135c6476f33ea0f7a7f10be9768ba3408e791",
-    "zh:961efe244a5163a3369817bdd1092aae2e58391d7e21929fab56473d62385d1d",
-    "zh:a08a965235e6db0233730b93a024e2b8a8c1567dd453eb0aa4aec59b9ed91558",
-    "zh:c031636938f665629ef3d48d771b6037571ddb886366ade241ed19551aaea24f",
-    "zh:cf8fc251e4ae701d5f2503f5d1b9f7e5f804f676a1b9b2d88a59930d6b7a9054",
-    "zh:d5fa2cc80a6361d92c5c725f677f93de5d98c9d644ac978f083a06a7381dda1d",
-    "zh:ecef5c1e59d1c6cde6aee407b79aecd76d6c129dcec4f67666085f0403a0f46a",
+    "h1:hgym1GEv8sMxDjl6IV9+8Qm8TG/HP9k4YDnsrvc5tNc=",
+    "zh:0bd650fb52e272f74eda5053a7bb62f0fd92182f57ad3ef742abe165cb8cac98",
+    "zh:1c36667aa89b672a96c0df3d3c613e80916a2d0944b1a1f9112065f40630b689",
+    "zh:21f90683890ea7a184b0ac55efd52911694ba86c58898bc8bbe87ee2507bb1eb",
+    "zh:24349d483a6ff97420d847433553fa031f68f99b9ead4ebb3592fc8955ef521f",
+    "zh:3fffd83c450bea2b382a986501ae51a4d3e6530eda48ed9ca74d518e4a909c37",
+    "zh:43d7de1dc4c50fae99d6c4ab4bb394608948091f5b53ddb29bc65deead9dc8a6",
+    "zh:47a37d5fec79dd8bc9cab2c892bc59e135b86cb51eebe2b01cdb40afac7ed777",
+    "zh:6efeb9530b8f57618c43f0b294b983d06cce43e9423bdd737eed81db913edb80",
+    "zh:7511ace4b33baddfc452ef95a634d83b92bfbfaa23cb30403899e95b64727075",
+    "zh:7bade77104ed8788c9b5171c7daae6ab6c011b3c40b152274fda803bf0bf2707",
+    "zh:83bce3ff9a1bd52a340a6ebdd2e2b731ec6fb86811ef0ed8a8264daf9d7beb61",
+    "zh:a09d5fce4c8d33e10b9a19318c965076db2d8ed5f62f5feb3e7502416f66d7bf",
+    "zh:c942832b80270eb982eeb9cc14f30a437db5fd28faf37d6aa32ec2cd345537d6",
+    "zh:e2c1812f2e1f9fac17c7551d4ab0efb713b6d751087c18b84b8acd542f587459",
   ]
 }
 
diff --git a/azure.tf b/azure.tf
new file mode 100644
index 0000000..a98e0df
--- /dev/null
+++ b/azure.tf
@@ -0,0 +1,35 @@
+data "azurerm_client_config" "current" {}
+
+resource "azurerm_resource_group" "forgejo_runners" {
+  name     = "Forgejo-Runners"
+  location = "West Europe"
+}
+
+resource "azurerm_key_vault" "forgejo_runners" {
+  name                       = "Forgejo-Runners"
+  location                   = azurerm_resource_group.forgejo_runners.location
+  resource_group_name        = azurerm_resource_group.forgejo_runners.name
+  tenant_id                  = data.azurerm_client_config.current.tenant_id
+  soft_delete_retention_days = 30
+  purge_protection_enabled   = false
+  enable_rbac_authorization  = true
+
+  sku_name = "standard"
+}
+
+resource "azurerm_resource_group" "infrastructure" {
+  name     = "Infrastructure"
+  location = "West Europe"
+}
+
+resource "azurerm_key_vault" "hetzner" {
+  name                       = "Hetzner"
+  location                   = azurerm_resource_group.infrastructure.location
+  resource_group_name        = azurerm_resource_group.infrastructure.name
+  tenant_id                  = data.azurerm_client_config.current.tenant_id
+  soft_delete_retention_days = 30
+  purge_protection_enabled   = false
+  enable_rbac_authorization  = true
+
+  sku_name = "standard"
+}
diff --git a/configs/ci-runner/50unattended-upgrades b/configs/ci-runner/50unattended-upgrades
new file mode 100644
index 0000000..6ecacba
--- /dev/null
+++ b/configs/ci-runner/50unattended-upgrades
@@ -0,0 +1,143 @@
+// Automatically upgrade packages from these (origin:archive) pairs
+//
+// Note that in Ubuntu security updates may pull in new dependencies
+// from non-security sources (e.g. chromium). By allowing the release
+// pocket these get automatically pulled in.
+Unattended-Upgrade::Allowed-Origins {
+	"${distro_id}:${distro_codename}";
+	"${distro_id}:${distro_codename}-security";
+	// Extended Security Maintenance; doesn't necessarily exist for
+	// every release and this system may not have it installed, but if
+	// available, the policy for updates is such that unattended-upgrades
+	// should also install from here by default.
+	"${distro_id}ESMApps:${distro_codename}-apps-security";
+	"${distro_id}ESM:${distro_codename}-infra-security";
+ 	"${distro_id}:${distro_codename}-updates";
+	"${distro_id}:${distro_codename}-proposed";
+	"${distro_id}:${distro_codename}-backports";
+};
+
+// Python regular expressions, matching packages to exclude from upgrading
+Unattended-Upgrade::Package-Blacklist {
+    // The following matches all packages starting with linux-
+//  "linux-";
+
+    // Use $ to explicitely define the end of a package name. Without
+    // the $, "libc6" would match all of them.
+//  "libc6$";
+//  "libc6-dev$";
+//  "libc6-i686$";
+
+    // Special characters need escaping
+//  "libstdc\+\+6$";
+
+    // The following matches packages like xen-system-amd64, xen-utils-4.1,
+    // xenstore-utils and libxenstore3.0
+//  "(lib)?xen(store)?";
+
+    // For more information about Python regular expressions, see
+    // https://docs.python.org/3/howto/regex.html
+};
+
+// This option controls whether the development release of Ubuntu will be
+// upgraded automatically. Valid values are "true", "false", and "auto".
+Unattended-Upgrade::DevRelease "auto";
+
+// This option allows you to control if on a unclean dpkg exit
+// unattended-upgrades will automatically run 
+//   dpkg --force-confold --configure -a
+// The default is true, to ensure updates keep getting installed
+//Unattended-Upgrade::AutoFixInterruptedDpkg "true";
+
+// Split the upgrade into the smallest possible chunks so that
+// they can be interrupted with SIGTERM. This makes the upgrade
+// a bit slower but it has the benefit that shutdown while a upgrade
+// is running is possible (with a small delay)
+Unattended-Upgrade::MinimalSteps "true";
+
+// Install all updates when the machine is shutting down
+// instead of doing it in the background while the machine is running.
+// This will (obviously) make shutdown slower.
+// Unattended-upgrades increases logind's InhibitDelayMaxSec to 30s.
+// This allows more time for unattended-upgrades to shut down gracefully
+// or even install a few packages in InstallOnShutdown mode, but is still a
+// big step back from the 30 minutes allowed for InstallOnShutdown previously.
+// Users enabling InstallOnShutdown mode are advised to increase
+// InhibitDelayMaxSec even further, possibly to 30 minutes.
+//Unattended-Upgrade::InstallOnShutdown "false";
+
+// Send email to this address for problems or packages upgrades
+// If empty or unset then no email is sent, make sure that you
+// have a working mail setup on your system. A package that provides
+// 'mailx' must be installed. E.g. "user@example.com"
+//Unattended-Upgrade::Mail "";
+
+// Set this value to one of:
+//    "always", "only-on-error" or "on-change"
+// If this is not set, then any legacy MailOnlyOnError (boolean) value
+// is used to chose between "only-on-error" and "on-change"
+//Unattended-Upgrade::MailReport "on-change";
+
+// Remove unused automatically installed kernel-related packages
+// (kernel images, kernel headers and kernel version locked tools).
+Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
+
+// Do automatic removal of newly unused dependencies after the upgrade
+Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
+
+// Do automatic removal of unused packages after the upgrade
+// (equivalent to apt-get autoremove)
+Unattended-Upgrade::Remove-Unused-Dependencies "false";
+
+// Automatically reboot *WITHOUT CONFIRMATION* if
+//  the file /var/run/reboot-required is found after the upgrade
+Unattended-Upgrade::Automatic-Reboot "true";
+
+// Automatically reboot even if there are users currently logged in
+// when Unattended-Upgrade::Automatic-Reboot is set to true
+//Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
+
+// If automatic reboot is enabled and needed, reboot at the specific
+// time instead of immediately
+//  Default: "now"
+Unattended-Upgrade::Automatic-Reboot-Time "06:00";
+
+// Use apt bandwidth limit feature, this example limits the download
+// speed to 70kb/sec
+//Acquire::http::Dl-Limit "70";
+
+// Enable logging to syslog. Default is False
+// Unattended-Upgrade::SyslogEnable "false";
+
+// Specify syslog facility. Default is daemon
+// Unattended-Upgrade::SyslogFacility "daemon";
+
+// Download and install upgrades only on AC power
+// (i.e. skip or gracefully stop updates on battery)
+// Unattended-Upgrade::OnlyOnACPower "true";
+
+// Download and install upgrades only on non-metered connection
+// (i.e. skip or gracefully stop updates on a metered connection)
+// Unattended-Upgrade::Skip-Updates-On-Metered-Connections "true";
+
+// Verbose logging
+// Unattended-Upgrade::Verbose "false";
+
+// Print debugging information both in unattended-upgrades and
+// in unattended-upgrade-shutdown
+// Unattended-Upgrade::Debug "false";
+
+// Allow package downgrade if Pin-Priority exceeds 1000
+// Unattended-Upgrade::Allow-downgrade "false";
+
+// When APT fails to mark a package to be upgraded or installed try adjusting
+// candidates of related packages to help APT's resolver in finding a solution
+// where the package can be upgraded or installed.
+// This is a workaround until APT's resolver is fixed to always find a
+// solution if it exists. (See Debian bug #711128.)
+// The fallback is enabled by default, except on Debian's sid release because
+// uninstallable packages are frequent there.
+// Disabling the fallback speeds up unattended-upgrades when there are
+// uninstallable packages at the expense of rarely keeping back packages which
+// could be upgraded or installed.
+// Unattended-Upgrade::Allow-APT-Mark-Fallback "true";
diff --git a/configs/ci-runner/docker-buildx-cleanup.service b/configs/ci-runner/docker-buildx-cleanup.service
new file mode 100644
index 0000000..7383e3f
--- /dev/null
+++ b/configs/ci-runner/docker-buildx-cleanup.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=Docker Buildx Cleanup Service
+Wants = network-online.target docker.service
+After = network.target network-online.target docker.service
+ConditionPathExists=/run/user/1000/docker.sock
+
+[Service]
+TimeoutStartSec=180
+KillMode=process
+User=runner
+Environment="DOCKER_HOST=unix:///run/user/1000/docker.sock"
+ExecStart=/usr/bin/docker buildx prune --force --max-used-space 10GB
+
+[Install]
+WantedBy=default.target
diff --git a/configs/ci-runner/docker-buildx-cleanup.timer b/configs/ci-runner/docker-buildx-cleanup.timer
new file mode 100644
index 0000000..8685fdb
--- /dev/null
+++ b/configs/ci-runner/docker-buildx-cleanup.timer
@@ -0,0 +1,9 @@
+[Unit]
+Description=Daily Docker Buildx Cleanup
+
+[Timer]
+OnBootSec=15min
+OnUnitActiveSec=1d
+
+[Install]
+WantedBy=timers.target
diff --git a/configs/ci-runner/runner-config.yaml b/configs/ci-runner/runner-config.yaml
index 32d71ab..9ded114 100644
--- a/configs/ci-runner/runner-config.yaml
+++ b/configs/ci-runner/runner-config.yaml
@@ -13,11 +13,11 @@ runner:
   fetch_timeout: 5s
   fetch_interval: 2s
   labels:
-    - "docker:docker://code.icb4dc0.de/infrastructure/images/act_runtime:24.04"
-    - "ubuntu-latest:docker://code.icb4dc0.de/infrastructure/images/act_runtime:24.04"
-    - "ubuntu-22.04:docker://code.icb4dc0.de/infrastructure/images/act_runtime:22.04"
-    - "ubuntu-latest-${arch}:docker://code.icb4dc0.de/infrastructure/images/act_runtime:24.04"
-    - "ubuntu-22.04-${arch}:docker://code.icb4dc0.de/infrastructure/images/act_runtime:22.04"
+    - "docker:docker://registry.icb4dc0.de/infrastructure/act_runtime:24.04"
+    - "ubuntu-latest:docker://registry.icb4dc0.de/infrastructure/act_runtime:24.04"
+    - "ubuntu-22.04:docker://registry.icb4dc0.de/infrastructure/act_runtime:22.04"
+    - "ubuntu-latest-${arch}:docker://registry.icb4dc0.de/infrastructure/act_runtime:24.04"
+    - "ubuntu-22.04-${arch}:docker://registry.icb4dc0.de/infrastructure/act_runtime:22.04"
 
 cache:
   enabled: true
diff --git a/dns.tf b/dns.tf
index 950f297..170ffd9 100644
--- a/dns.tf
+++ b/dns.tf
@@ -1,53 +1,62 @@
 resource "cloudflare_zone" "icb4dc0de" {
-  account_id = var.cloudflare_account_id
-  zone       = "icb4dc0.de"
-
+  account = {
+    id = data.azurerm_key_vault_secret.cloudflare_account_id.value
+  }
+  name = "icb4dc0.de"
+  type = "full"
+  
   lifecycle {
-    ignore_changes = [account_id]
+    ignore_changes = [account.id]
   }
 }
 
-resource "cloudflare_record" "mx_primary" {
+resource "cloudflare_dns_record" "mx_primary" {
   zone_id  = cloudflare_zone.icb4dc0de.id
-  name     = "@"
+  name     = cloudflare_zone.icb4dc0de.name
   type     = "MX"
+  ttl      = 1
   content  = "mx01.mail.icloud.com"
   priority = 10
 }
 
 
-resource "cloudflare_record" "mx_secondary" {
+resource "cloudflare_dns_record" "mx_secondary" {
   zone_id  = cloudflare_zone.icb4dc0de.id
-  name     = "@"
+  name     = cloudflare_zone.icb4dc0de.name
   type     = "MX"
+  ttl      = 1
   content  = "mx02.mail.icloud.com"
   priority = 10
 }
 
-resource "cloudflare_record" "apple_proof" {
+resource "cloudflare_dns_record" "apple_proof" {
   zone_id = cloudflare_zone.icb4dc0de.id
-  name    = "@"
+  name    = cloudflare_zone.icb4dc0de.name
   type    = "TXT"
+  ttl     = 1
   content = "apple-domain=chwbVvzH8hWIgg1l"
 }
 
-resource "cloudflare_record" "keybase_proof" {
+resource "cloudflare_dns_record" "keybase_proof" {
   zone_id = cloudflare_zone.icb4dc0de.id
-  name    = "@"
+  name    = cloudflare_zone.icb4dc0de.name
   type    = "TXT"
+  ttl     = 1
   content = "keybase-site-verification=WDQoLtW22epD7eQnts6rPKJBGA0lD6jSI6m0bGMYWag"
 }
 
-resource "cloudflare_record" "apple_spf" {
+resource "cloudflare_dns_record" "apple_spf" {
   zone_id = cloudflare_zone.icb4dc0de.id
-  name    = "@"
+  name    = cloudflare_zone.icb4dc0de.name
   type    = "TXT"
+  ttl     = 1
   content = "\"v=spf1 include:icloud.com ~all\""
 }
 
-resource "cloudflare_record" "apple_sig_domainkey" {
+resource "cloudflare_dns_record" "apple_sig_domainkey" {
   zone_id = cloudflare_zone.icb4dc0de.id
-  name    = "sig1._domainkey"
+  name    = "sig1._domainkey.${cloudflare_zone.icb4dc0de.name}"
   type    = "CNAME"
+  ttl     = 1
   content = "sig1.dkim.icb4dc0.de.at.icloudmailadmin.com"
-}
\ No newline at end of file
+}
diff --git a/forgejo-runner_machines.tf b/forgejo-runner_machines.tf
index 8521ace..ce8c7c6 100644
--- a/forgejo-runner_machines.tf
+++ b/forgejo-runner_machines.tf
@@ -19,7 +19,6 @@ resource "hcloud_placement_group" "forgejo_runners" {
   }
 }
 
-
 resource "hcloud_server" "forgejo_runner" {
   for_each           = var.forgejo_runners
   name               = each.key
@@ -29,7 +28,7 @@ resource "hcloud_server" "forgejo_runner" {
   placement_group_id = hcloud_placement_group.k3s_machines.id
 
   backups = false
-  
+
   user_data = data.cloudinit_config.runner_config[each.key].rendered
 
   lifecycle {
@@ -68,14 +67,20 @@ resource "hcloud_server" "forgejo_runner" {
   }
 }
 
+data "azurerm_key_vault_secret" "runner_secret" {
+  for_each     = var.forgejo_runners
+  name         = "${each.key}-runner-secret"
+  key_vault_id = azurerm_key_vault.forgejo_runners.id
+}
+
 data "cloudinit_config" "runner_config" {
-  for_each = var.forgejo_runners
-  gzip = true
+  for_each      = var.forgejo_runners
+  gzip          = true
   base64_encode = true
-  
+
   part {
     content_type = "text/cloud-config"
-    content = <<-EOF
+    content      = <<-EOF
       groups:
         - docker
       users:
@@ -105,7 +110,7 @@ data "cloudinit_config" "runner_config" {
             keyid: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88
     EOF
   }
-  
+
   part {
     content_type = "text/cloud-config"
     content = <<-EOF
@@ -116,6 +121,12 @@ data "cloudinit_config" "runner_config" {
             owner: root:root
             permissions: "0644"
 
+          - encoding: gzip+base64
+            content: ${base64gzip(file("configs/ci-runner/50unattended-upgrades"))}
+            path: /etc/apt/apt.conf.d/50unattended-upgrades
+            owner: root:root
+            permissions: "0644"
+
           - encoding: gzip+base64
             content: ${base64gzip(file("configs/ci-runner/forgejo-runner.service"))}
             path: /etc/systemd/user/forgejo-runner.service
@@ -123,10 +134,24 @@ data "cloudinit_config" "runner_config" {
             permissions: "0640"
             defer: true
 
+          - encoding: gzip+base64
+            content: ${base64gzip(file("configs/ci-runner/docker-buildx-cleanup.service"))}
+            path: /lib/systemd/system/docker-buildx-cleanup.service
+            owner: root:root
+            permissions: "0640"
+            defer: true
+
+          - encoding: gzip+base64
+            content: ${base64gzip(file("configs/ci-runner/docker-buildx-cleanup.timer"))}
+            path: /lib/systemd/system/docker-buildx-cleanup.timer
+            owner: root:root
+            permissions: "0640"
+            defer: true            
+
           - encoding: gzip+base64
             content: ${base64gzip(templatefile("configs/ci-runner/runner-config.yaml", {
-              arch = startswith(each.value.server_type, "cax") ? "arm64" : "amd64"
-            }))}
+    arch = startswith(each.value.server_type, "cax") ? "arm64" : "amd64"
+}))}
             path: /etc/act/config.yaml
             owner: runner:runner
             permissions: "0640"
@@ -138,6 +163,13 @@ data "cloudinit_config" "runner_config" {
             owner: root:root
             permissions: "0640"
             defer: true
+
+          - encoding: gzip+base64
+            content: ${base64gzip(data.azurerm_key_vault_secret.runner_secret[each.key].value)}
+            path: /var/lib/runner/.runner
+            owner: runner:runner
+            permissions: "0640"
+            defer: true
             
           - encoding: gzip+base64
             content: ${base64gzip(file("configs/ci-runner/daemon.json"))}
@@ -145,12 +177,12 @@ data "cloudinit_config" "runner_config" {
             owner: runner:runner
             permissions: "0640"
             defer: true
-  EOF
-  }
-  
-  part {
-    content_type = "text/cloud-config"
-    content      = <<-EOF
+    EOF
+}
+
+part {
+  content_type = "text/cloud-config"
+  content      = <<-EOF
       runcmd:
         - |
           set -e
@@ -168,9 +200,9 @@ data "cloudinit_config" "runner_config" {
           gpg --verify /tmp/forgejo-runner.asc /usr/local/bin/forgejo-runner
           chmod +x /usr/local/bin/forgejo-runner
           
-          sudo -u runner forgejo-runner register --config /etc/act/config.yaml --no-interactive --token ${var.forgejo_runner_secret} --name ${each.key} --instance ${var.forgejo_instance_url}
-          
           sudo -u runner DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus XDG_RUNTIME_DIR=/run/user/1000 systemctl --user enable --now forgejo-runner.service
+          systemctl enable --now docker-buildx-cleanup.timer
+          systemctl restart unattended-upgrades.service
     EOF
-  }
+}
 }
diff --git a/k8s_control_plane.tf b/k8s_control_plane.tf
index 566aeef..803692a 100644
--- a/k8s_control_plane.tf
+++ b/k8s_control_plane.tf
@@ -88,25 +88,27 @@ resource "hcloud_server" "control-plane" {
   }
 }
 
-resource "cloudflare_record" "cp-host-ipv4" {
+resource "cloudflare_dns_record" "cp-host-ipv4" {
   for_each = var.k3s_control_plane
 
   depends_on = [hcloud_server.control-plane]
 
   zone_id = cloudflare_zone.icb4dc0de.id
-  name    = "${each.key}.k8s"
+  name    = "${each.key}.k8s.${cloudflare_zone.icb4dc0de.name}"
   type    = "A"
+  ttl     = 1
   content = hcloud_server.control-plane[each.key].ipv4_address
 }
 
-resource "cloudflare_record" "cp-host-ipv6" {
+resource "cloudflare_dns_record" "cp-host-ipv6" {
   for_each = var.k3s_control_plane
 
   depends_on = [hcloud_server.control-plane]
 
   zone_id = cloudflare_zone.icb4dc0de.id
-  name    = "${each.key}.k8s"
+  name    = "${each.key}.k8s.${cloudflare_zone.icb4dc0de.name}"
   type    = "AAAA"
+  ttl     = 1
   content = hcloud_server.control-plane[each.key].ipv6_address
 }
 
@@ -116,21 +118,21 @@ data "ct_config" "machine-ignitions-cp" {
   content = templatefile(
     "${path.module}/configs/cp/k3s-flatcar.yaml",
     {
-      "host"               = "${each.key}"
-      "k3s_token"          = "${var.k3s_token}"
-      "litestream_version" = "${var.litestream_version}",
+      "host"               = each.key
+      "k3s_token"          = data.azurerm_key_vault_secret.k3s_token.value
+      "litestream_version" = var.litestream_version,
       "litestream_config" = base64encode(
         templatefile(
           "${path.module}/configs/cp/litestream.yml",
           {
-            "accessKey" = var.k3s_backup_access_key,
-            "secretKey" = var.k3s_backup_secret_key,
-            "endpoint"  = var.k3s_backup_endpoint
+            "accessKey" = data.azurerm_key_vault_secret.k3s_backup_access_key.value,
+            "secretKey" = data.azurerm_key_vault_secret.k3s_backup_secret_key.value,
+            "endpoint"  = data.azurerm_key_vault_secret.k3s_backup_endpoint.value
           }
         )
       )
-      "node_ip"     = "${each.value.private_ip}"
-      "k3s_version" = "${var.control_plane_k3s_version}",
+      "node_ip"     = each.value.private_ip
+      "k3s_version" = var.control_plane_k3s_version,
       "k3s_sans"    = var.k3s_sans,
     }
   )
diff --git a/k8s_flatcar_machines.tf b/k8s_flatcar_machines.tf
index 3543b78..ccba069 100644
--- a/k8s_flatcar_machines.tf
+++ b/k8s_flatcar_machines.tf
@@ -109,7 +109,7 @@ data "ct_config" "machine-ignitions" {
     "${path.module}/configs/workers/k3s-flatcar.yaml",
     {
       "host"              = each.key
-      "k3s_token"         = var.k3s_token
+      "k3s_token"         = data.azurerm_key_vault_secret.k3s_token.value
       "node_ip"           = each.value.private_ip
       "k3s_version"       = var.worker_k3s_version
       "spin_shim_version" = var.spin_shim_version
diff --git a/key_vault_secrets.tf b/key_vault_secrets.tf
new file mode 100644
index 0000000..09efd20
--- /dev/null
+++ b/key_vault_secrets.tf
@@ -0,0 +1,24 @@
+data "azurerm_key_vault_secret" "k3s_token" {
+  name         = "k3s-token"
+  key_vault_id = azurerm_key_vault.hetzner.id
+}
+
+data "azurerm_key_vault_secret" "k3s_backup_access_key" {
+  name         = "k3s-backup-access-key"
+  key_vault_id = azurerm_key_vault.hetzner.id
+}
+
+data "azurerm_key_vault_secret" "k3s_backup_secret_key" {
+  name         = "k3s-backup-secret-key"
+  key_vault_id = azurerm_key_vault.hetzner.id
+}
+
+data "azurerm_key_vault_secret" "k3s_backup_endpoint" {
+  name         = "k3s-backup-endpoint"
+  key_vault_id = azurerm_key_vault.hetzner.id
+}
+
+data "azurerm_key_vault_secret" "cloudflare_account_id" {
+  name         = "cloudflare-account-id"
+  key_vault_id = azurerm_key_vault.hetzner.id
+}
diff --git a/main.tf b/main.tf
index 9e65eb6..c421615 100644
--- a/main.tf
+++ b/main.tf
@@ -1,7 +1,9 @@
 provider "hcloud" {
-  token = var.hcloud_token
 }
 
 provider "cloudflare" {
-  api_token = var.cloudflare_api_token
-}
\ No newline at end of file
+}
+
+provider "azurerm" {
+  features {}
+}
diff --git a/tf.sh b/tf.sh
index 30dc6aa..ed90c96 100755
--- a/tf.sh
+++ b/tf.sh
@@ -1,33 +1,19 @@
 #!/usr/bin/env bash
 
-# export AWS_ACCESS_KEY=$(rbw get -f username "CloudFlare TFState")
-# export AWS_SECRET_KEY=$(rbw get "CloudFlare TFState")
-# export HETZNER_DNS_API_TOKEN=$(rbw get -f "API Token" "Hetzner DNS")
-# export TF_VAR_hcloud_token="$(rbw get "HCloud API")"
-# export TF_VAR_k3s_token="$(rbw get "K3s Token")"
-# export TF_VAR_forgejo_runner_secret="$(rbw get "Forgejo Runner Secret")"
-# export TF_VAR_k3s_backup_access_key="$(rbw get -f username "K3s Backup")"
-# export TF_VAR_k3s_backup_secret_key="$(rbw get "K3s Backup")"
-# export TF_VAR_k3s_backup_endpoint="$(rbw get -f Endpoint "K3s Backup")"
-# export TF_VAR_cloudflare_api_token="$(rbw get -f "DNS API Token" "CloudFlare")"
-# export TF_VAR_cloudflare_account_id="$(rbw get -f "Account ID" "CloudFlare")"
-
 docker run \
     --rm \
     -ti \
+    --pull=always \
     --platform linux/arm64 \
     --workdir=/srv/workspace \
     --mount type=bind,source=.,target=/srv/workspace \
     -e AWS_ACCESS_KEY=$(rbw get -f username "CloudFlare TFState") \
     -e AWS_SECRET_KEY=$(rbw get "CloudFlare TFState") \
-    -e HETZNER_DNS_API_TOKEN=$(rbw get -f "API Token" "Hetzner DNS") \
-    -e TF_VAR_hcloud_token="$(rbw get "HCloud API")" \
-    -e TF_VAR_k3s_token="$(rbw get "K3s Token")" \
-    -e TF_VAR_forgejo_runner_secret="$(rbw get "Forgejo Runner Secret")" \
-    -e TF_VAR_k3s_backup_access_key="$(rbw get -f username "K3s Backup")" \
-    -e TF_VAR_k3s_backup_secret_key="$(rbw get "K3s Backup")" \
-    -e TF_VAR_k3s_backup_endpoint="$(rbw get -f Endpoint "K3s Backup")" \
-    -e TF_VAR_cloudflare_api_token="$(rbw get -f "DNS API Token" "CloudFlare")" \
-    -e TF_VAR_cloudflare_account_id="$(rbw get -f "Account ID" "CloudFlare")" \
+    -e ARM_CLIENT_ID=$(rbw get -f username "Azure Infrastructure App Registration") \
+    -e ARM_CLIENT_SECRET=$(rbw get "Azure Infrastructure App Registration") \
+    -e ARM_TENANT_ID=$(rbw get -f TenantID "Azure Infrastructure App Registration") \
+    -e ARM_SUBSCRIPTION_ID=$(rbw get -f SubscriptionID "Azure Infrastructure App Registration") \
+    -e HCLOUD_TOKEN="$(rbw get "HCloud API")" \
+    -e CLOUDFLARE_API_TOKEN="$(rbw get -f "DNS API Token" "CloudFlare")" \
     ghcr.io/opentofu/opentofu:latest \
     $@
diff --git a/vars.tf b/vars.tf
index b2e08bc..3ed89ad 100644
--- a/vars.tf
+++ b/vars.tf
@@ -1,37 +1,3 @@
-variable "hcloud_token" {
-  type      = string
-  sensitive = true
-}
-
-variable "cloudflare_api_token" {
-  type      = string
-  sensitive = true
-}
-
-variable "cloudflare_account_id" {
-  type      = string
-  sensitive = true
-}
-
-variable "k3s_token" {
-  type      = string
-  sensitive = true
-}
-
-variable "k3s_backup_access_key" {
-  sensitive = true
-  type      = string
-}
-
-variable "k3s_backup_secret_key" {
-  sensitive = true
-  type      = string
-}
-
-variable "k3s_backup_endpoint" {
-  type = string
-}
-
 variable "litestream_version" {
   type    = string
   default = "v0.3.13"
@@ -52,14 +18,9 @@ variable "worker_k3s_version" {
   default = "v1.32.1+k3s1"
 }
 
-variable "forgejo_runner_secret" {
-  type      = string
-  sensitive = true
-}
-
 variable "forgejo_runner_version" {
   type    = string
-  default = "6.2.2"
+  default = "6.3.1"
 }
 
 variable "forgejo_instance_url" {
diff --git a/versions.tf b/versions.tf
index d94c985..a357a07 100644
--- a/versions.tf
+++ b/versions.tf
@@ -17,27 +17,32 @@ terraform {
   required_providers {
     hcloud = {
       source  = "hetznercloud/hcloud"
-      version = "1.48.0"
+      version = "1.50.0"
     }
 
     cloudflare = {
       source  = "cloudflare/cloudflare"
-      version = "4.40.0"
+      version = "5.2.0"
+    }
+
+    azurerm = {
+      source  = "hashicorp/azurerm"
+      version = "4.24.0"
     }
 
     ct = {
       source  = "poseidon/ct"
       version = "0.13.0"
     }
-    
+
     cloudinit = {
-      source = "hashicorp/cloudinit"
-      version = "2.3.5"
+      source  = "hashicorp/cloudinit"
+      version = "2.3.6"
     }
 
     null = {
       source  = "hashicorp/null"
-      version = "~> 3.2.2"
+      version = "~> 3.2.3"
     }
   }
 }