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
Normal file
119
.terraform.lock.hcl
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…
Reference in a new issue