Migrate opentofu part
This commit is contained in:
		
							parent
							
								
									344710e831
								
							
						
					
					
						commit
						f872d2199b
					
				
					 12 changed files with 596 additions and 0 deletions
				
			
		
							
								
								
									
										3
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -2,3 +2,6 @@ | ||||||
| 
 | 
 | ||||||
| types-dnscontrol.d.ts | types-dnscontrol.d.ts | ||||||
| dns/hosts.json | dns/hosts.json | ||||||
|  | 
 | ||||||
|  | secrets.auto.tfvars | ||||||
|  | .terraform | ||||||
|  |  | ||||||
							
								
								
									
										119
									
								
								.terraform.lock.hcl
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								.terraform.lock.hcl
									
										
									
										generated
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,119 @@ | ||||||
|  | # This file is maintained automatically by "tofu init". | ||||||
|  | # Manual edits may be lost in future updates. | ||||||
|  | 
 | ||||||
|  | provider "registry.opentofu.org/hashicorp/template" { | ||||||
|  |   version = "2.2.0" | ||||||
|  |   hashes = [ | ||||||
|  |     "h1:tdS0otiAtvUV8uLJWJNfcqOPo3llj7FyRzExw6X1srY=", | ||||||
|  |     "zh:374c28bafc43cd65e578cb209efc9eee4c1cec7618f451528e928db98059e8c8", | ||||||
|  |     "zh:6a2982e70fbc2ab2668d624c648ef2eb32243c1a1185246b03991a7a21326db9", | ||||||
|  |     "zh:af83169c21bb13f141510a349e1f70cf7d893247a269bd71cad74dd22f1df0f5", | ||||||
|  |     "zh:b81a5bedc91a1a81b938c393247248d6c3d1bd8ea685541f9c858908c0afb6b3", | ||||||
|  |     "zh:de15486244af2d29d44d510d647cd6e0b1408e89952261013c572b7c9bfd744b", | ||||||
|  |   ] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | provider "registry.opentofu.org/hashicorp/time" { | ||||||
|  |   version = "0.12.0" | ||||||
|  |   hashes = [ | ||||||
|  |     "h1:Om7xF0GgRkBsAjKis3RAFXQJKmHgnO04C+PEScF/xTM=", | ||||||
|  |     "zh:01b7ac8203eb7ed712a356215e44f8851b96ddcfdf63b13ff9f870f799667059", | ||||||
|  |     "zh:06c4420bdb964209eb119f1740575df7b8ac44a3b5d71631dae2962a155f58b7", | ||||||
|  |     "zh:2534d1d04ca934e25426ab5bb0b29a57a95c676f70b154bfb382d58bf1e6f6c9", | ||||||
|  |     "zh:340de6c71a1090f13ab5c429ca2134c12189e8b86c2b104859e82eb30eea9772", | ||||||
|  |     "zh:561a2780f7fb1b0a9092c59c4eb3e3d8c3ec9cecddc9214ae92fdc941c3bd2e7", | ||||||
|  |     "zh:65b1a982617375123bc3a1dcd44d61264cabac6b3d83378e7079ee0655ec6679", | ||||||
|  |     "zh:9ae9f6c9609c5ed9e35a702068629ef5adfb131f957a571fc39ce0127c782ca4", | ||||||
|  |     "zh:ad7f066c5db340683cb5a3a29ced3a2ece13c5b84c46d6b3d30815444a6c78ee", | ||||||
|  |     "zh:f532d2c33c2303a970e9ee813e37d208eb65321aec489da14786b7f04ea66105", | ||||||
|  |     "zh:fb269e2425a4b996fef79665eaeec8f40a388bf7ac7bf8ce2c108fb83c4b10ca", | ||||||
|  |   ] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | provider "registry.opentofu.org/hetznercloud/hcloud" { | ||||||
|  |   version     = "1.48.1" | ||||||
|  |   constraints = "~> 1.45" | ||||||
|  |   hashes = [ | ||||||
|  |     "h1:fa9fxdSV9DG+HDcXyRbcGfb6Dk94SBP3TamHb1yOYiI=", | ||||||
|  |     "zh:086cce10cb005f25f85183c59e639d6675e91e919934c80f660ca1cc4b9bc09b", | ||||||
|  |     "zh:111d185707168b90c7ed3d245b522b2bd508f0bd4275496a1acdc9c0adaa85f2", | ||||||
|  |     "zh:1acba3f30150282d283c46cd7ce25e9afb8b027fd2f594d41de9131d25a42b27", | ||||||
|  |     "zh:1f8858aa81f93d52550502a11c7ea4e9370316ab098f6b75a09ffe75da6129ee", | ||||||
|  |     "zh:20e01e6e6f99f57b3c1ef2a9de5d617c0139d3f3934eeb5e6c5976ae8b831a48", | ||||||
|  |     "zh:2a8489a586a7bdadc42bbc9e3cb7b9deaefdf8020e3f2caba2678877d5d64d52", | ||||||
|  |     "zh:31d8017529b0429bc9e873ec5d358ab9b75af2ba0ae24f21abcd4d09f36b7ee9", | ||||||
|  |     "zh:407b4d7f1407e7e4a51b6f4dcdb0c7fbf81f2f1e25a7275f34054009419125a2", | ||||||
|  |     "zh:42cf7cf867d199054713d4e6060e4b578eff16f0f537e9aaa5fd990c3eab8bc6", | ||||||
|  |     "zh:460ac856ff952c5d41525949b93cfb7ee642f900594eff965494f11999d7496b", | ||||||
|  |     "zh:d09e527d23f62564c82bc24e286cf2cb8cb0ed6cdc6f4c66adf2145cfa62adac", | ||||||
|  |     "zh:d465356710444ac70dea4883252efc429b73e79fc6dc94f075662b838476680e", | ||||||
|  |     "zh:d476c8eca307e30a20eed54c0735b062a6f3066b4ac63eebecd38ab8f40c16f4", | ||||||
|  |     "zh:e0e9b2f6d5e28dbd01fa1ec3147aa88062d6223c5146532a3dcd1d3bb827e1e9", | ||||||
|  |   ] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | provider "registry.opentofu.org/ovh/ovh" { | ||||||
|  |   version     = "0.48.0" | ||||||
|  |   constraints = "~> 0.48" | ||||||
|  |   hashes = [ | ||||||
|  |     "h1:dOwImR7DGX4FHt9IpY6S7z8z62fyhTOiLm0kgSA+MfE=", | ||||||
|  |     "zh:64ae6a94f86115d6a0cf54e62de16f3751f2f511c7c133a58734b623ecd83133", | ||||||
|  |     "zh:808c0dfc35f0cdde84fff2b772ef52aef57363e2f496ae8e5b5d191ae2482db3", | ||||||
|  |     "zh:91427314fe73ee5bb3cc0fdcc88c15416709ff049751573674cb56a17ebf137f", | ||||||
|  |     "zh:97a60491d8a50900c83365ab86343f59ae39a6a8d0ecbf2229be389143c584af", | ||||||
|  |     "zh:a2be10afc172ea844706217143b003c21dd502fcfe429fa61f5cebdbd2c38c55", | ||||||
|  |     "zh:a6e0e5978a6b1247a110e1bf2461771e3bf1b3c974cc83b56ae3255cdc5123d3", | ||||||
|  |     "zh:b6cac2ddd451cb783faab09ec90a54be222a2bc9ef59eaaec309980b46a8650c", | ||||||
|  |     "zh:d767fc3a8c992fa01be52a86ba92204d5ac7ea238a2ebce5e313eaf56e4ae3ac", | ||||||
|  |     "zh:ed2f82995fbe92d7a750a9560cb325d6dbee1b031898dba4ab74447c6043c878", | ||||||
|  |     "zh:ef20c721c5349f03106aa3514752b1df3583ce96a0e704a4b45d9b4b455ca57b", | ||||||
|  |     "zh:f33f42bca65d40097033f0e64e45ad113107804be2198a2279d5561bb1122b34", | ||||||
|  |     "zh:f922c6d3d73f8c252beb91dc9f97eb96643781ad3e7192018be47d4df2e4d0e3", | ||||||
|  |     "zh:f93577ad688f449c03c4087a19cea3cc37bc30c94519eee4710323099bf501ad", | ||||||
|  |     "zh:ff33c4b2543030a82935551631d209df87adf981b4661a4ab60406e704fe7485", | ||||||
|  |   ] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | provider "registry.opentofu.org/scaleway/scaleway" { | ||||||
|  |   version     = "2.44.0" | ||||||
|  |   constraints = "~> 2.43" | ||||||
|  |   hashes = [ | ||||||
|  |     "h1:VRA4GE/N4YaxrsDi4VtCvTa2F2VMz6cHvig+uXx95Ys=", | ||||||
|  |     "zh:07626890d5417058f5999675304f039036253a2b17eb1b658cb4d8a9dd783cdd", | ||||||
|  |     "zh:153fb6d63f7e7203cbadd35f0ec46f8a1ce2bee16817a3f7c2b7f908d833fe9e", | ||||||
|  |     "zh:2d535d419d2c44810d538e06769afc02ca529f59d4340f563d4ca040f6c43f35", | ||||||
|  |     "zh:3097ffad52ea5102dfd1c0693e86f812634a029dd1a98fb8a448154daa6063fc", | ||||||
|  |     "zh:562477ee7953c836a1133e20158911ff3d831167689a691b58ce7f6954e636b5", | ||||||
|  |     "zh:71c4168c400b421fa1edaee1970473b6f3abe3f76d2ea5c2ef2292df9f909bcb", | ||||||
|  |     "zh:82c6c6c81a5dd911f33f5363d777f0009689a83fb7bf219e958717e4d9ed0e23", | ||||||
|  |     "zh:88daeb4b398e7806a1c94afce439238bf2abcb290e8c65eb3ea7e0c42c1442b1", | ||||||
|  |     "zh:a1e83eda0c66140d86239b3830a258fa98f2e964bd52f2a8f3cc97aca2390166", | ||||||
|  |     "zh:d7d7e37de2a66d5048e19797edd59358c357f26ac03beab9fec36c1838969ad2", | ||||||
|  |     "zh:dc0692b3378057e18354a1f7aa87e64f7b84ed8e9c005b9ad69bf01638f88246", | ||||||
|  |     "zh:e32409c6dfd397c297dfb702f8dff0ae3c9592c017a24148fec8379c1a67e50c", | ||||||
|  |     "zh:e4aa8b3bbfbe1b5bc9a06b32a68e30def2af91c886e6008a5d4b7d6a5e18f46f", | ||||||
|  |     "zh:ef08071c2c4a398c6c287a26e2255831afe5b2049416d7e7c23117f199687676", | ||||||
|  |   ] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | provider "registry.opentofu.org/tailscale/tailscale" { | ||||||
|  |   version     = "0.16.2" | ||||||
|  |   constraints = "~> 0.16" | ||||||
|  |   hashes = [ | ||||||
|  |     "h1:m8r5+K4JWe+tdT4IyryZkAQ7d38GVPtoQ9mzp+5Scaw=", | ||||||
|  |     "zh:2a37ef43b88ad8e26ecad79e6b34a896769be2b7d18140f855f6063775367841", | ||||||
|  |     "zh:3867d3331b59c8281dd8a742260b22e18750ae84a9bd2009e8f9d90412d2c044", | ||||||
|  |     "zh:5e5e5ee08e0ecefa08a0ce7a9281a858f9b3a2a66bc9c06802b1624a1cb3eae0", | ||||||
|  |     "zh:6298e8ed55bccd5513060e0d357d055919b3a22146fcfb6c34881efd49ec33f8", | ||||||
|  |     "zh:6ce0ab6564fbbc673ab98ce4b7db7d64258a916394436a005d14b25c3ea58ad1", | ||||||
|  |     "zh:6fdc1fb66074d2af5124a6988f81efdc77011b185e710629140e87ffb8624956", | ||||||
|  |     "zh:7ff7888d77a17b18c9bdc9dfc1bf1e7f98f512410c29d1a8c2e6c21c8fe2a5c4", | ||||||
|  |     "zh:9cafb8660daffd5c9c490d4529c7ba3d691fee5e4093b55e73f188b17e34cead", | ||||||
|  |     "zh:b11e0e1b6c8485eb832336a69be02dfae151b71350e25288ec7bf0637df35485", | ||||||
|  |     "zh:c7371d0dcde253fcd1808f86be2fcfc6e0b6ec82aa714e5dc6b533ba10007d48", | ||||||
|  |     "zh:dcddd847b8a03a3b7c9288d68e781d65a3b911ef9cc96df9502a2d069195ae42", | ||||||
|  |     "zh:dfd37ec661fe5b1520b595dcb93cca65f716270edc173a393a600c85b3f842d7", | ||||||
|  |     "zh:e3b623167859344ed93f4125e97d24c5793246ccb329e4d82b2d9d8e5c356380", | ||||||
|  |     "zh:f4d38ec08191ae70ef05ffd3943df1c27e2b11192a02e1979498a59ea1881ee3", | ||||||
|  |   ] | ||||||
|  | } | ||||||
							
								
								
									
										63
									
								
								hcloud.tf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								hcloud.tf
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,63 @@ | ||||||
|  | resource "hcloud_ssh_key" "openpgp_0xAB920993" { | ||||||
|  |   name       = "openpgp:0xAB920993" | ||||||
|  |   public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCkmWZmum4cVeDy5+9N1HdUzfnjEHSJ900ucD8F0wAy4MV1cdPYnZ4u5PFv5XMfmvA9SJ+VFsr0lhYlr+GQBG9aCCAdMJVVmEz3SccT6dp6ZYywT158RNshzfCe9ylWKK80+W7XnDXhdkec7aK+BQn5wOER3A3mUqRR0JDXWga9jyakH1K6OwXmQOO419bJWs2uCT1ZEgndHxKJEt2pEvoSz7z8p1SS2zyro+R3YtvL9WiDo3+0yPFYficNDr7s39yF5IJE+KTqAlCn5R2+kJ54lRmzB8oNS2jGwK2Q6wtph4AmfnlJTMODG2U2RjUltH2MIDXIYe2epATWL8qhkI4LTr38C7QR3DeJQsel/yTWdYqGakvU6Ge/xkbsaWOrSDTV3bPgKHzlL+dIKaGpV+5usZN4fpOLOb/nmYy3ekLpobzxza7rBRT2CxXS72DoPFaRE1ye7SxhcsLBNwre9YQFE4VvUZwJYkWz2V7eqGrk8VYnmQmT/bnUnMnVwMpeDc7pFKAFndIUxifoOj77c98Tdy3ncdS7SOd7+zRbLG+7k0UU1k89o1+tfREAddUJYR4RvB6g0kCyjpwOf1Pt4zhJR3y/zpsCCc5UnzK9X2kEo/8TSyvTr+GBiFVp5yLYgwCPJSNna33YX7+c3oLRM1QGgtqZk9qnGX9hgP8qpF8Akw== openpgp:0xAB920993" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | data "template_file" "cloud_init" { | ||||||
|  |   template = "${file("./tf-templates/cloud-init.yaml.tpl")}" | ||||||
|  | 
 | ||||||
|  |   vars = { | ||||||
|  |     tailscale_authkey = "${tailscale_tailnet_key.cloud_init_key.key}" | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | locals { | ||||||
|  |   hetzner_hosts = {for key, val in var.hosts : key => val if val.provider == "hetzner"} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | resource "hcloud_primary_ip" "node_ipv4_addresses" { | ||||||
|  |   for_each      = local.hetzner_hosts | ||||||
|  |   name          = "primary_ipv4_${each.value.hostname}" | ||||||
|  |   datacenter    = each.value.datacenter | ||||||
|  |   type          = "ipv4" | ||||||
|  |   assignee_type = "server" | ||||||
|  |   auto_delete   = false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | resource "hcloud_primary_ip" "node_ipv6_addresses" { | ||||||
|  |   for_each      = local.hetzner_hosts | ||||||
|  |   name          = "primary_ipv6_${each.value.hostname}" | ||||||
|  |   datacenter    = each.value.datacenter | ||||||
|  |   type          = "ipv6" | ||||||
|  |   assignee_type = "server" | ||||||
|  |   auto_delete   = false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | # Create a server | ||||||
|  | resource "hcloud_server" "nodes" { | ||||||
|  |   for_each    = local.hetzner_hosts | ||||||
|  |   name        = each.value.hostname | ||||||
|  |   datacenter  = each.value.datacenter | ||||||
|  |   image       = each.value.image | ||||||
|  |   server_type = each.value.server_type | ||||||
|  |   ssh_keys    = [hcloud_ssh_key.openpgp_0xAB920993.id] | ||||||
|  |   user_data   = "${data.template_file.cloud_init.rendered}" | ||||||
|  |   public_net { | ||||||
|  |     ipv4 = hcloud_primary_ip.node_ipv4_addresses[each.key].id | ||||||
|  |     ipv6 = hcloud_primary_ip.node_ipv6_addresses[each.key].id | ||||||
|  |   } | ||||||
|  |   lifecycle { | ||||||
|  |     ignore_changes = [ | ||||||
|  |       ssh_keys, | ||||||
|  |       user_data | ||||||
|  |     ] | ||||||
|  |    prevent_destroy = true | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | resource "hcloud_rdns" "nodes_rdns" { | ||||||
|  |   for_each   = local.hetzner_hosts | ||||||
|  |   server_id  = hcloud_server.nodes[each.key].id | ||||||
|  |   ip_address = hcloud_server.nodes[each.key].ipv4_address | ||||||
|  |   dns_ptr    = each.value.rdns | ||||||
|  | } | ||||||
							
								
								
									
										24
									
								
								hosts.auto.tfvars
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								hosts.auto.tfvars
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | ||||||
|  | hosts = { | ||||||
|  |   "node001" = { | ||||||
|  |     hostname = "node001" | ||||||
|  |     rdns = "node001.serguzim.net" | ||||||
|  |     provider = "contabo" | ||||||
|  |     ipv4_address = "144.91.106.67", | ||||||
|  |     ipv6_address = "2a02:c207:2051:6620::1" | ||||||
|  |   }, | ||||||
|  |   "node002" = { | ||||||
|  |     hostname = "node002" | ||||||
|  |     rdns = "node002.serguzim.net" | ||||||
|  |     provider = "contabo" | ||||||
|  |     ipv4_address = "62.171.181.192", | ||||||
|  |     ipv6_address = "2a02:c207:2036:6681::1" | ||||||
|  |   }, | ||||||
|  |   "node003" = { | ||||||
|  |     hostname = "node003" | ||||||
|  |     rdns = "mail.serguzim.me" | ||||||
|  |     provider = "hetzner" | ||||||
|  |     image = "debian-12" | ||||||
|  |     server_type = "cx32" | ||||||
|  |     datacenter = "fsn1-dc14" | ||||||
|  |   }, | ||||||
|  | } | ||||||
							
								
								
									
										63
									
								
								main.tf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								main.tf
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,63 @@ | ||||||
|  | terraform { | ||||||
|  |   required_providers { | ||||||
|  |     hcloud = { | ||||||
|  |       source = "hetznercloud/hcloud" | ||||||
|  |       version = "~> 1.45" | ||||||
|  |     } | ||||||
|  |     ovh = { | ||||||
|  |       source = "ovh/ovh" | ||||||
|  |       version = "~> 0.48" | ||||||
|  |     } | ||||||
|  |     scaleway = { | ||||||
|  |       source = "scaleway/scaleway" | ||||||
|  |       version = "~> 2.43" | ||||||
|  |     } | ||||||
|  |     tailscale = { | ||||||
|  |       source = "tailscale/tailscale" | ||||||
|  |       version = "~> 0.16" | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   backend "s3" { | ||||||
|  |     bucket         = var.backend_bucket | ||||||
|  |     access_key     = var.backend_access_key | ||||||
|  |     secret_key     = var.backend_secret_key | ||||||
|  |     key            = "terraform.tfstate" | ||||||
|  |     region         = var.backend_region | ||||||
|  |     encrypt        = true | ||||||
|  |     endpoints      = { | ||||||
|  |       s3           = var.backend_endpoint | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     # Disable AWS-specific features | ||||||
|  |     skip_credentials_validation = true | ||||||
|  |     skip_region_validation      = true | ||||||
|  |     skip_requesting_account_id  = true | ||||||
|  |     skip_s3_checksum            = true | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | provider "hcloud" { | ||||||
|  |   token = "${var.hcloud_token}" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | provider "ovh" { | ||||||
|  |   endpoint = "ovh-eu" | ||||||
|  |   application_key = "${var.ovh_application_key}" | ||||||
|  |   application_secret = "${var.ovh_application_secret}" | ||||||
|  |   consumer_key = "${var.ovh_consumer_key}" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | provider "scaleway" { | ||||||
|  |   organization_id = "${var.scaleway_organization_id}" | ||||||
|  |   project_id = "${var.scaleway_project_id}" | ||||||
|  |   access_key = "${var.scaleway_access_key}" | ||||||
|  |   secret_key = "${var.scaleway_secret_key}" | ||||||
|  |   region = "nl-ams" | ||||||
|  |   zone = "nl-ams-1" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | provider "tailscale" { | ||||||
|  |   api_key = "${var.tailscale_api_key}" | ||||||
|  |   tailnet = "${var.tailscale_tailnet}" | ||||||
|  | } | ||||||
							
								
								
									
										20
									
								
								output.tf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								output.tf
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | ||||||
|  | output "hosts" { | ||||||
|  |   value = { | ||||||
|  |     for subdomain in distinct([for record in ovh_domain_zone_record.server_records : record.subdomain]) :  | ||||||
|  |     subdomain => { | ||||||
|  |       "ipv4_address" = try( | ||||||
|  |         ovh_domain_zone_record.server_records["${subdomain}:ipv4"].target,  | ||||||
|  |         null | ||||||
|  |       ) | ||||||
|  |       "ipv6_address" = try( | ||||||
|  |         ovh_domain_zone_record.server_records["${subdomain}:ipv6"].target,  | ||||||
|  |         null | ||||||
|  |       ) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | output "scaleway_service_keys" { | ||||||
|  |   value       = scaleway_iam_api_key.service_keys | ||||||
|  |   sensitive   = true | ||||||
|  | } | ||||||
							
								
								
									
										74
									
								
								ovh.tf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								ovh.tf
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,74 @@ | ||||||
|  | locals { | ||||||
|  |   contabo_hosts = {for key, val in var.hosts : key => val if val.provider == "contabo"} | ||||||
|  |   server_addresses = flatten([ | ||||||
|  |     [ | ||||||
|  |       for host in local.contabo_hosts : [ | ||||||
|  |         { | ||||||
|  |           hostname = host.hostname | ||||||
|  |           ipv4_address = host.ipv4_address | ||||||
|  |           ipv6_address = host.ipv6_address | ||||||
|  |         }, | ||||||
|  |       ] | ||||||
|  |     ], | ||||||
|  |     [ | ||||||
|  |       for host in hcloud_server.nodes : [ | ||||||
|  |         { | ||||||
|  |           hostname = host.name | ||||||
|  |           ipv4_address = host.ipv4_address | ||||||
|  |           ipv6_address = host.ipv6_address | ||||||
|  |         }, | ||||||
|  |       ] | ||||||
|  |     ] | ||||||
|  |   ]) | ||||||
|  | 
 | ||||||
|  |   server_addresses_separated = flatten([ | ||||||
|  |     for host in local.server_addresses : [ | ||||||
|  |       { | ||||||
|  |         hostname = host.hostname | ||||||
|  |         key      = "${host.hostname}:ipv4" | ||||||
|  |         address  = host.ipv4_address | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         hostname = host.hostname | ||||||
|  |         key      = "${host.hostname}:ipv6" | ||||||
|  |         address  = host.ipv6_address | ||||||
|  |       }, | ||||||
|  |     ] | ||||||
|  |   ]) | ||||||
|  | 
 | ||||||
|  |   tailscale_host_addresses = flatten([ | ||||||
|  |     for host in data.tailscale_devices.nodes.devices : [ | ||||||
|  |       for index, address in host.addresses : { | ||||||
|  |         hostname = host.hostname | ||||||
|  |         key      = "${host.hostname}:${index}" | ||||||
|  |         address  = address | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   ]) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | resource "ovh_domain_zone_record" "server_records" { | ||||||
|  |   for_each  = { for entry in local.server_addresses_separated: entry.key => entry } | ||||||
|  |   zone      = "serguzim.net" | ||||||
|  |   subdomain = each.value.hostname | ||||||
|  |   fieldtype = strcontains(each.value.address, ":") ? "AAAA" : "A" | ||||||
|  |   ttl       = 3600 | ||||||
|  |   target    = each.value.address | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | resource "ovh_domain_zone_record" "tailscale_vpn" { | ||||||
|  |   for_each  = { for entry in local.tailscale_host_addresses: entry.key => entry } | ||||||
|  |   zone      = "serguzim.net" | ||||||
|  |   subdomain = "${each.value.hostname}.vpn" | ||||||
|  |   fieldtype = strcontains(each.value.address, ":") ? "AAAA" : "A" | ||||||
|  |   ttl       = 600 | ||||||
|  |   target    = each.value.address | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | resource "ovh_domain_zone_record" "status_page_cname" { | ||||||
|  |   zone      = "serguzim.net" | ||||||
|  |   subdomain = "status" | ||||||
|  |   fieldtype = "CNAME" | ||||||
|  |   ttl       = 3600 | ||||||
|  |   target    = "status.serguzim.me." | ||||||
|  | } | ||||||
							
								
								
									
										77
									
								
								scaleway.tf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								scaleway.tf
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,77 @@ | ||||||
|  | data "scaleway_account_project" "project" { | ||||||
|  |   project_id = "${var.scaleway_project_id}" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | resource "scaleway_account_ssh_key" "openpgp_0xAB920993" { | ||||||
|  |   name = "openpgp:0xAB920993" | ||||||
|  |   public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCkmWZmum4cVeDy5+9N1HdUzfnjEHSJ900ucD8F0wAy4MV1cdPYnZ4u5PFv5XMfmvA9SJ+VFsr0lhYlr+GQBG9aCCAdMJVVmEz3SccT6dp6ZYywT158RNshzfCe9ylWKK80+W7XnDXhdkec7aK+BQn5wOER3A3mUqRR0JDXWga9jyakH1K6OwXmQOO419bJWs2uCT1ZEgndHxKJEt2pEvoSz7z8p1SS2zyro+R3YtvL9WiDo3+0yPFYficNDr7s39yF5IJE+KTqAlCn5R2+kJ54lRmzB8oNS2jGwK2Q6wtph4AmfnlJTMODG2U2RjUltH2MIDXIYe2epATWL8qhkI4LTr38C7QR3DeJQsel/yTWdYqGakvU6Ge/xkbsaWOrSDTV3bPgKHzlL+dIKaGpV+5usZN4fpOLOb/nmYy3ekLpobzxza7rBRT2CxXS72DoPFaRE1ye7SxhcsLBNwre9YQFE4VvUZwJYkWz2V7eqGrk8VYnmQmT/bnUnMnVwMpeDc7pFKAFndIUxifoOj77c98Tdy3ncdS7SOd7+zRbLG+7k0UU1k89o1+tfREAddUJYR4RvB6g0kCyjpwOf1Pt4zhJR3y/zpsCCc5UnzK9X2kEo/8TSyvTr+GBiFVp5yLYgwCPJSNna33YX7+c3oLRM1QGgtqZk9qnGX9hgP8qpF8Akw== openpgp:0xAB920993" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | resource "scaleway_iam_application" "service_applications" { | ||||||
|  |   for_each = var.service_buckets | ||||||
|  |   name = each.value.name | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | resource "scaleway_iam_policy" "service_storage_policies" { | ||||||
|  |   for_each = var.service_buckets | ||||||
|  |   name = "${each.key}_storage_policy" | ||||||
|  |   application_id = scaleway_iam_application.service_applications[each.key].id | ||||||
|  |   rule { | ||||||
|  |     project_ids = [data.scaleway_account_project.project.id] | ||||||
|  |     permission_set_names = ["ObjectStorageFullAccess"] | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | resource "scaleway_object_bucket" "service_buckets" { | ||||||
|  |   for_each = var.service_buckets | ||||||
|  |   name = "${each.value.name}.serguzim.me" | ||||||
|  |   lifecycle { | ||||||
|  |    prevent_destroy = true | ||||||
|  |  } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | resource "scaleway_object_bucket_policy" "service_bucket_policies" { | ||||||
|  |   for_each = var.service_buckets | ||||||
|  |   bucket = scaleway_object_bucket.service_buckets[each.key].id | ||||||
|  |   policy = jsonencode({ | ||||||
|  |     Version = "2023-04-17", | ||||||
|  |     Id = "${each.key}_bucket_policy", | ||||||
|  |     Statement = [ | ||||||
|  |       { | ||||||
|  |         Sid = "Scaleway secure statement" | ||||||
|  |         Effect = "Allow" | ||||||
|  |         Action = "*" | ||||||
|  |         Principal = { | ||||||
|  |           SCW = "user_id:${var.scaleway_user_id}" | ||||||
|  |         } | ||||||
|  |         Resource = [ | ||||||
|  |           "${scaleway_object_bucket.service_buckets[each.key].name}", | ||||||
|  |           "${scaleway_object_bucket.service_buckets[each.key].name}/*", | ||||||
|  |         ] | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         Sid = "${each.key} statement" | ||||||
|  |         Effect = "Allow" | ||||||
|  |         Action = "*" | ||||||
|  |         Principal = { | ||||||
|  |           SCW = "application_id:${scaleway_iam_application.service_applications[each.key].id}" | ||||||
|  |         } | ||||||
|  |         Resource = [ | ||||||
|  |           "${scaleway_object_bucket.service_buckets[each.key].name}", | ||||||
|  |           "${scaleway_object_bucket.service_buckets[each.key].name}/*", | ||||||
|  |         ] | ||||||
|  |       }, | ||||||
|  |     ] | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | resource "time_rotating" "rotate_after_a_year" { | ||||||
|  |   rotation_years = 1 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | resource "scaleway_iam_api_key" "service_keys" { | ||||||
|  |   for_each       = var.service_buckets | ||||||
|  |   description    = "Service key for ${each.key}" | ||||||
|  |   application_id = scaleway_iam_application.service_applications[each.key].id | ||||||
|  |   expires_at     = time_rotating.rotate_after_a_year.rotation_rfc3339 | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								service_buckets.auto.tfvars
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								service_buckets.auto.tfvars
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | ||||||
|  | service_buckets = { | ||||||
|  |   "linkwarden" = { | ||||||
|  |     name = "linkwarden" | ||||||
|  |     bucket = "linkwarden.serguzim.me" | ||||||
|  |   }, | ||||||
|  |   "harbor" = { | ||||||
|  |     name = "harbor" | ||||||
|  |     bucket = "harbor.serguzim.me" | ||||||
|  |   } | ||||||
|  |   "forgejo" = { | ||||||
|  |     name = "forgejo" | ||||||
|  |     bucket = "forgejo.serguzim.me" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								tailscale.tf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								tailscale.tf
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | ||||||
|  | resource "tailscale_tailnet_key" "cloud_init_key" { | ||||||
|  |   reusable      = true | ||||||
|  |   ephemeral     = false | ||||||
|  |   preauthorized = true | ||||||
|  |   expiry        = 3600 | ||||||
|  |   description   = "Cloud-init key used by opentofu" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | data "tailscale_devices" "nodes" { | ||||||
|  |   name_prefix = "node" | ||||||
|  | } | ||||||
							
								
								
									
										40
									
								
								tf-templates/cloud-init.yaml.tpl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								tf-templates/cloud-init.yaml.tpl
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | ||||||
|  | #cloud-config | ||||||
|  | 
 | ||||||
|  | users: | ||||||
|  |   - name: serguzim | ||||||
|  |     gecos: Serguzim | ||||||
|  |     groups: users,admin,wheel | ||||||
|  |     sudo: "ALL=(ALL) ALL" | ||||||
|  |     shell: /bin/bash | ||||||
|  |     lock_passwd: false | ||||||
|  |     ssh_authorized_keys: | ||||||
|  |       - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCkmWZmum4cVeDy5+9N1HdUzfnjEHSJ900ucD8F0wAy4MV1cdPYnZ4u5PFv5XMfmvA9SJ+VFsr0lhYlr+GQBG9aCCAdMJVVmEz3SccT6dp6ZYywT158RNshzfCe9ylWKK80+W7XnDXhdkec7aK+BQn5wOER3A3mUqRR0JDXWga9jyakH1K6OwXmQOO419bJWs2uCT1ZEgndHxKJEt2pEvoSz7z8p1SS2zyro+R3YtvL9WiDo3+0yPFYficNDr7s39yF5IJE+KTqAlCn5R2+kJ54lRmzB8oNS2jGwK2Q6wtph4AmfnlJTMODG2U2RjUltH2MIDXIYe2epATWL8qhkI4LTr38C7QR3DeJQsel/yTWdYqGakvU6Ge/xkbsaWOrSDTV3bPgKHzlL+dIKaGpV+5usZN4fpOLOb/nmYy3ekLpobzxza7rBRT2CxXS72DoPFaRE1ye7SxhcsLBNwre9YQFE4VvUZwJYkWz2V7eqGrk8VYnmQmT/bnUnMnVwMpeDc7pFKAFndIUxifoOj77c98Tdy3ncdS7SOd7+zRbLG+7k0UU1k89o1+tfREAddUJYR4RvB6g0kCyjpwOf1Pt4zhJR3y/zpsCCc5UnzK9X2kEo/8TSyvTr+GBiFVp5yLYgwCPJSNna33YX7+c3oLRM1QGgtqZk9qnGX9hgP8qpF8Akw== openpgp:0xAB920993" | ||||||
|  |   - name: ansible | ||||||
|  |     gecos: Ansible User | ||||||
|  |     groups: users,admin,wheel | ||||||
|  |     sudo: "ALL=(ALL) NOPASSWD:ALL" | ||||||
|  |     shell: /bin/bash | ||||||
|  |     lock_passwd: true | ||||||
|  |     ssh_authorized_keys: | ||||||
|  |       - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCkmWZmum4cVeDy5+9N1HdUzfnjEHSJ900ucD8F0wAy4MV1cdPYnZ4u5PFv5XMfmvA9SJ+VFsr0lhYlr+GQBG9aCCAdMJVVmEz3SccT6dp6ZYywT158RNshzfCe9ylWKK80+W7XnDXhdkec7aK+BQn5wOER3A3mUqRR0JDXWga9jyakH1K6OwXmQOO419bJWs2uCT1ZEgndHxKJEt2pEvoSz7z8p1SS2zyro+R3YtvL9WiDo3+0yPFYficNDr7s39yF5IJE+KTqAlCn5R2+kJ54lRmzB8oNS2jGwK2Q6wtph4AmfnlJTMODG2U2RjUltH2MIDXIYe2epATWL8qhkI4LTr38C7QR3DeJQsel/yTWdYqGakvU6Ge/xkbsaWOrSDTV3bPgKHzlL+dIKaGpV+5usZN4fpOLOb/nmYy3ekLpobzxza7rBRT2CxXS72DoPFaRE1ye7SxhcsLBNwre9YQFE4VvUZwJYkWz2V7eqGrk8VYnmQmT/bnUnMnVwMpeDc7pFKAFndIUxifoOj77c98Tdy3ncdS7SOd7+zRbLG+7k0UU1k89o1+tfREAddUJYR4RvB6g0kCyjpwOf1Pt4zhJR3y/zpsCCc5UnzK9X2kEo/8TSyvTr+GBiFVp5yLYgwCPJSNna33YX7+c3oLRM1QGgtqZk9qnGX9hgP8qpF8Akw== openpgp:0xAB920993" | ||||||
|  | 
 | ||||||
|  | packages: | ||||||
|  |   - git | ||||||
|  |   - vim | ||||||
|  | 
 | ||||||
|  | runcmd: | ||||||
|  |   ############################################################ | ||||||
|  |   ### Configure sshd ### Configure sshd ### Configure sshd ### | ||||||
|  |   ############################################################ | ||||||
|  |   - sed -i 's/\#\?Port .\+/Port 17/' /etc/ssh/sshd_config | ||||||
|  |   - sed -i 's/\#\?PasswordAuthentication .\+/PasswordAuthentication no/' /etc/ssh/sshd_config | ||||||
|  |   - sed -i 's/\#\?PermitRootLogin .\+/PermitRootLogin no/' /etc/ssh/sshd_config | ||||||
|  |   - systemctl restart sshd | ||||||
|  | 
 | ||||||
|  |   ##################################################################### | ||||||
|  |   ### Install tailscale ### Install tailscale ### Install tailscale ### | ||||||
|  |   ##################################################################### | ||||||
|  |   # One-command install, from https://tailscale.com/download/ | ||||||
|  |   - ['sh', '-c', 'curl -fsSL https://tailscale.com/install.sh | sh'] | ||||||
|  |   - ['tailscale', 'up', '--authkey=${tailscale_authkey}'] | ||||||
|  | 
 | ||||||
							
								
								
									
										88
									
								
								variables.tf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								variables.tf
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,88 @@ | ||||||
|  | variable "backend_access_key" { | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | variable "backend_secret_key" { | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | variable "backend_endpoint" { | ||||||
|  |   sensitive = false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | variable "backend_region" { | ||||||
|  |   sensitive = false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | variable "backend_bucket" { | ||||||
|  |   sensitive = false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | variable "hcloud_token" { | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | variable "ovh_application_key" { | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | variable "ovh_application_secret" { | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | variable "ovh_consumer_key" { | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | variable "scaleway_user_id" { | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | variable "scaleway_organization_id" { | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | variable "scaleway_project_id" { | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | variable "scaleway_access_key" { | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | variable "scaleway_secret_key" { | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | variable "tailscale_api_key" { | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | variable "tailscale_tailnet" { | ||||||
|  |   sensitive = false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | variable "service_buckets" { | ||||||
|  |   type = map(object({ | ||||||
|  |     name = string | ||||||
|  |     bucket = string | ||||||
|  |   })) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | variable "hosts" { | ||||||
|  |   type = map(object({ | ||||||
|  |     hostname = string | ||||||
|  |     rdns = string | ||||||
|  |     provider = string | ||||||
|  |     ipv4_address = optional(string) | ||||||
|  |     ipv6_address = optional(string) | ||||||
|  |     image = optional(string) | ||||||
|  |     server_type = optional(string) | ||||||
|  |     datacenter = optional(string) | ||||||
|  |   })) | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue