diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..84fc8e5 --- /dev/null +++ b/.envrc @@ -0,0 +1,7 @@ +# Automatically sets up your devbox environment whenever you cd into this +# directory via our direnv integration: + +eval "$(devbox generate direnv --print-envrc)" + +# check out https://www.jetpack.io/devbox/docs/ide_configuration/direnv/ +# for more details diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..27a9393 --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +# ---> Terraform +# Local .terraform directories +**/.terraform/* + +# .tfstate files +**/*.tfstate +**/*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Exclude all .tfvars files, which are likely to contain sensitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +*.tfvars +*.tfvars.json + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc + +# ENV +.env +admin.*config + +# Nix +result diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c8cac82 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +ARG NGINX_VERSION=1.27.1 +FROM nginx:$NGINX_VERSION AS build + +RUN mkdir -p /var/lib/GeoIP/ + +RUN apt-get update \ + && apt-get install -y \ + build-essential \ + libpcre2-dev \ + zlib1g-dev \ + libgeoip-dev \ + libmaxminddb-dev \ + wget \ + git + +ARG GEOIP2_VERSION=3.4 +RUN cd /opt \ + && git clone --depth 1 -b $GEOIP2_VERSION --single-branch https://github.com/leev/ngx_http_geoip2_module.git \ + && wget -O - http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz | tar zxfv - \ + && mv /opt/nginx-$NGINX_VERSION /opt/nginx \ + && cd /opt/nginx \ + && ./configure --with-compat --add-dynamic-module=/opt/ngx_http_geoip2_module --with-stream \ + && make modules + +# Production +FROM nginx:$NGINX_VERSION AS production + +COPY --from=build /opt/nginx/objs/ngx_http_geoip2_module.so /usr/lib/nginx/modules +COPY --from=build /opt/nginx/objs/ngx_stream_geoip2_module.so /usr/lib/nginx/modules + +RUN apt-get update \ + && apt-get install -y --no-install-recommends --no-install-suggests libmaxminddb0 \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + && chmod -R 644 /usr/lib/nginx/modules/ngx_http_geoip2_module.so \ + && chmod -R 644 /usr/lib/nginx/modules/ngx_stream_geoip2_module.so diff --git a/configuration.nix b/configuration.nix new file mode 100644 index 0000000..64caa71 --- /dev/null +++ b/configuration.nix @@ -0,0 +1,13 @@ +{ + inputs, + lib, + config, + pkgs, + ... +} : { + system.stateVersion = "23.11"; + + environment.systemPackages = [ + pkgs.nginx + ]; +} diff --git a/devbox.json b/devbox.json new file mode 100644 index 0000000..87ae00a --- /dev/null +++ b/devbox.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json", + "packages": [ + "tflint@latest", + "tenv@latest" + ], + "env": { + "TENV_AUTO_INSTALL": "true" + }, + "shell": { + "init_hook": [ + "echo 'Welcome to devbox!' > /dev/null" + ], + "scripts": { + "test": [ + "echo \"Error: no test specified\" && exit 1" + ] + } + } +} diff --git a/devbox.lock b/devbox.lock new file mode 100644 index 0000000..fcf0f43 --- /dev/null +++ b/devbox.lock @@ -0,0 +1,101 @@ +{ + "lockfile_version": "1", + "packages": { + "tenv@latest": { + "last_modified": "2024-08-18T12:44:29Z", + "resolved": "github:NixOS/nixpkgs/ff1c2669bbb4d0dd9e62cc94f0968cfa652ceec1#tenv", + "source": "devbox-search", + "version": "3.0.0", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/0zbz338z744cmpp0z2rmzygab4b8pili-tenv-3.0.0", + "default": true + } + ], + "store_path": "/nix/store/0zbz338z744cmpp0z2rmzygab4b8pili-tenv-3.0.0" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/fiwf4p798kamjy6waaqn0nl6dvzrz6r0-tenv-3.0.0", + "default": true + } + ], + "store_path": "/nix/store/fiwf4p798kamjy6waaqn0nl6dvzrz6r0-tenv-3.0.0" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/g87m0hmaqlb9gcg2c8ln1lx9fyzqx1m0-tenv-3.0.0", + "default": true + } + ], + "store_path": "/nix/store/g87m0hmaqlb9gcg2c8ln1lx9fyzqx1m0-tenv-3.0.0" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/x22lfx74nns131xxmnhpnnn7gz6hfp1r-tenv-3.0.0", + "default": true + } + ], + "store_path": "/nix/store/x22lfx74nns131xxmnhpnnn7gz6hfp1r-tenv-3.0.0" + } + } + }, + "tflint@latest": { + "last_modified": "2024-08-18T12:44:29Z", + "resolved": "github:NixOS/nixpkgs/ff1c2669bbb4d0dd9e62cc94f0968cfa652ceec1#tflint", + "source": "devbox-search", + "version": "0.52.0", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/2kqp4ba1anc4c1vxm31criv2cnw7bm8i-tflint-0.52.0", + "default": true + } + ], + "store_path": "/nix/store/2kqp4ba1anc4c1vxm31criv2cnw7bm8i-tflint-0.52.0" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/zq3wrj237i9v6jvjfiiglhqrxnn5yfbl-tflint-0.52.0", + "default": true + } + ], + "store_path": "/nix/store/zq3wrj237i9v6jvjfiiglhqrxnn5yfbl-tflint-0.52.0" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/57xd6fdjgkhyi8p69bik9bhjz3nxz4gk-tflint-0.52.0", + "default": true + } + ], + "store_path": "/nix/store/57xd6fdjgkhyi8p69bik9bhjz3nxz4gk-tflint-0.52.0" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/ldy3j1qq62nq1fm9q3rpmnd0glpzvfma-tflint-0.52.0", + "default": true + } + ], + "store_path": "/nix/store/ldy3j1qq62nq1fm9q3rpmnd0glpzvfma-tflint-0.52.0" + } + } + } + } +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..aaca5fc --- /dev/null +++ b/flake.lock @@ -0,0 +1,101 @@ +{ + "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixlib": { + "locked": { + "lastModified": 1723942470, + "narHash": "sha256-QdSArN0xKESEOTcv+3kE6yu4B4WX9lupZ4+Htx3RXGg=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "531a2e8416a6d8200a53eddfbdb8f2c8dc4a1251", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixos-generators": { + "inputs": { + "nixlib": "nixlib", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1724028932, + "narHash": "sha256-U11ZiQPrpIBdv7oS23bNdX9GCxe/hPf/ARr64P2Wj1Y=", + "owner": "nix-community", + "repo": "nixos-generators", + "rev": "5fd22603892e4ec5ac6085058ed658243143aacd", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixos-generators", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1720535198, + "narHash": "sha256-zwVvxrdIzralnSbcpghA92tWu2DV2lwv89xZc8MTrbg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "205fd4226592cc83fd4c0885a3e4c9c400efabb5", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixos-generators": "nixos-generators", + "nixpkgs": "nixpkgs", + "xc": "xc" + } + }, + "xc": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1724081153, + "narHash": "sha256-j2bfrmjBSf87ByVSGUaNzHk3Hh605/rOjar3slWAhjQ=", + "owner": "joerdav", + "repo": "xc", + "rev": "48e28d6f29623b0c2eedce688fcb7d29f0d2976e", + "type": "github" + }, + "original": { + "owner": "joerdav", + "repo": "xc", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..5ae0374 --- /dev/null +++ b/flake.nix @@ -0,0 +1,49 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11"; + nixos-generators = { + url = "github:nix-community/nixos-generators"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + xc = { + url = "github:joerdav/xc"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { nixpkgs, nixos-generators, xc, ... }: + let + pkgsForSystem = system: import nixpkgs { + inherit system; + overlays = [ + (final: prev: { xc = xc.packages.${system}.xc; }) + ]; + }; + allVMs = [ "x86_64-linux" "aarch64-linux" ]; + forAllVMs = f: nixpkgs.lib.genAttrs allVMs (system: f { + inherit system; + pkgs = pkgsForSystem system; + }); + in + { + packages = forAllVMs ({ system, pkgs }: { + vm = nixos-generators.nixosGenerate { + format = "proxmox"; + system = system; + + specialArgs = { + pkgs = pkgs; + #diskSize = "8G"; + }; + + modules = [ + # Pin nixpkgs to the flake input, so that the packages installed + # come from the flake inputs.nixpkgs.url. + ({ ... }: { nix.registry.nixpkgs.flake = nixpkgs; }) + # Apply the rest of the config. + ./configuration.nix + ]; + }; + }); + }; +} diff --git a/justfile b/justfile new file mode 100644 index 0000000..674e068 --- /dev/null +++ b/justfile @@ -0,0 +1,26 @@ +# Always use devbox environment to run commands. +set shell := ["devbox", "run"] +# Load dotenv +set dotenv-load + +export TENV_AUTO_INSTALL := "true" + +default: + @just --list + +lint: + @tofu fmt -check -recursive . + @tflint --recursive + +build: + @nix build .#vm + +deploy: + #!/usr/bin/env sh + export NIX_RESULT_DIR=$(nix build --print-out-paths .#vm) + export IMAGE_NAME=$(ls ${NIX_RESULT_DIR} | grep ".vma.zst") + export TF_VAR_image_path=${NIX_RESULT_DIR}/${IMAGE_NAME} + + cd {{justfile_directory()}}/terraform + tofu init + tofu apply diff --git a/terraform/.terraform.lock.hcl b/terraform/.terraform.lock.hcl new file mode 100644 index 0000000..3354b09 --- /dev/null +++ b/terraform/.terraform.lock.hcl @@ -0,0 +1,89 @@ +# This file is maintained automatically by "tofu init". +# Manual edits may be lost in future updates. + +provider "registry.opentofu.org/bpg/proxmox" { + version = "0.61.1" + constraints = "0.61.1" + hashes = [ + "h1:6kz2Rdjc8+TVq2aUxEQXLOwbb9OdhJJei0L1fC4K2R4=", + "zh:27d8b589a2dc1e0a5b0f8ab299b9f3704a2f0b69799d1d4d8845c68056986d1f", + "zh:46dfa6b33ddd7007a2144f38090457604eb56a59a303b37bb0ad1be5c84ddaca", + "zh:47a1b14a759393c5ecc76f2feb950677c418c910b8c677fde0dd3e4675c41579", + "zh:582e49d109d1c2b1f3b1268a7cbc43548f3c6d96a87c92a5428767097a5e383e", + "zh:5e98ad6afae5969a4c3ffb14c0484936550c66c8313d7686551c29b633ff32f2", + "zh:7b9e24b76f947ab8f1e571cf61beefc983b7d2aa1b85df35c4f015728fe37a38", + "zh:8255ca210f279a0f7b8ca2762df26d2ea1a01704298c5e3d5cf601bd39a743f0", + "zh:85d7655fdc95dedced9cf8105a0beeb0d7bc8f668c55f62019a7215a76d60300", + "zh:8aeea5a1d001b06baaf923b754e1a14d06c75eb8c8b87a7f65a3c8205fc8b079", + "zh:a9cfab6c06f613658c5fdd83742cd22c0eb7563778924b1407965ef8c36c1ce0", + "zh:ceaab67801d49a92eb5858b1ddae6df2569462e5ffbe31f9dbd79dcb684ea142", + "zh:dc25b506d5c55d1d78a335d3ebd03213c99b4b2a5859812349a955c2f746ff7e", + "zh:e04b477fd77a0d37a0bdb76a7cf69184dad9e7fbba9b4f3a378a8901b82b75e5", + "zh:f1e6838d9141557f73340df9b21fce5a82b41cc16ae36f063a920ccc36bc0758", + "zh:f26e0763dbe6a6b2195c94b44696f2110f7f55433dc142839be16b9697fa5597", + ] +} + +provider "registry.opentofu.org/digitalocean/digitalocean" { + version = "2.40.0" + constraints = "~> 2.0" + hashes = [ + "h1:Y7VkuuqOBgv+1jgL/4Hi247K2BskXwXtR/Uk9ssK/e4=", + "zh:00235830abae70642ebefc4d9c00e5eb978e28b74abc6b34f16b078f242aa217", + "zh:09d77785f768bd568f85a121d3d79316083befe903ce4ccd5567689a23236fb0", + "zh:0c9c4e19b411702d316a6bd044903e2ec506a69d38495ed32cc31e3f3f26acae", + "zh:12b34c88faad5b6149e9a3ad1396680588e1bae263b20d6b19835460f111c190", + "zh:15f041fc57ea46673a828919efe2ef3f05f7c4b863b7d7881336b93e92bd1159", + "zh:45e01972de2fab1687a09ea8fb3e4519be11c93ef93a63f28665630850858a20", + "zh:4e18bf5c1d2ec1ec6b6a9f4b58045309006f510edf770168fc18e273e6a09289", + "zh:575528b7e36e3489d2309e0c6cb9bd9952595cac5459b914f2d2827de1a1e4fc", + "zh:67462192212f810875d556462c79f574a8f5713b7a869ba4fce25953bfcf2dd2", + "zh:7024637b31e8276b653265fdf3f479220182edde4b300b034562b4c287faefa5", + "zh:a7904721b2680be8330dde98dd826be15c67eb274da7876f042cbcd6592ac970", + "zh:b225d4b67037a19392b0ab00d1f5fc9e729db4dfc32d18d4b36225693270ef52", + "zh:bd1e8768819d6113b2ec16f939196a1f2ae6d2803824fde463a20d06e071b212", + "zh:c5da40dc0749548ee2e1943776fb41b952c994e50bbc404251df20a81f730242", + "zh:dabc3387392aaba297739e1e97fadf059258fc3efb4dff2f499dbc407b6e088d", + "zh:f42137cf424c3e7c9c935b3f73618e51096bd0367a8d364073e2d70588d2cbf2", + ] +} + +provider "registry.opentofu.org/hashicorp/dns" { + version = "3.4.1" + constraints = "~> 3.4.1" + hashes = [ + "h1:6Tb2wZRxfKunvjLw47ihfkaoARWIQrJd+WCOXkx0hg4=", + "zh:53f46f16fc3b25d9bdce61d7cc9a67cea9c67ea5347fcde35833451d5011f1c4", + "zh:662669802c99c7e698ca52e7a32afc19acf66d97bbc05f5effacdf0fe471848f", + "zh:8289aee49df8a0cb2fcdfded575e68df1721fc3e6ce75555def499d31b7e910d", + "zh:90aa9b049d19137ed15ea3f88238824e1fde7d1a806378cb97520391e169a96d", + "zh:9e5795e10d65927ba689cfabc06b72085055543342d1db26ef5963ae5ab5d64a", + "zh:9f39b6e0ca35cf2405fe4e13af8a405cf9b0b0c34b6b06ad36f319631405a3aa", + "zh:c37a2c140c95b3eaa9d0aeb79496b220ba1a0456d01a77fcc68bd565bee7edd5", + "zh:cd40d356c5382f0b868df2d8539f95031e3cf0c210053674ec4c7cd20c73b82a", + "zh:fde59f09e4e62fc84012fff8493bc64eac287a0245e1c8abf29b0138d3018dfb", + "zh:ffee5b54936bd43247e9316de0ecc0dde36556a2cd50f090d7f6443a3f689b95", + ] +} + +provider "registry.opentofu.org/tailscale/tailscale" { + version = "0.16.1" + constraints = "0.16.1" + hashes = [ + "h1:NDIIkEo0G/leQSvGoh2Mk74ZE2xWrWgHX/S8ZVyBDYU=", + "zh:0a9d28e5195e0e29ebf9b12b345cafcb686125008151fa01677c399d8f8f1321", + "zh:249bce2fcfd3414211ae9e49e179e31b5d3c23dd9da24dc45acdea34ad308cb0", + "zh:3129fb52a2aaa0c8c30aff21e7d4c0601d80898b3ecb9d7604b5933c14f54924", + "zh:4ec3e255f34bb4f6362ab41aa9e05a3ce040a791bc07445dec86188dee867f85", + "zh:68d3995e5a1722e24f89a385899f56a63542159b884cac989196e9538b53c6ce", + "zh:799840b3bfbd14537397f157f4e6a5e54080cd4fee51521bac675aa188e0b33e", + "zh:99f1da9fdaddd8a1255dce56edf8eb3e235293c72738cf70f1fb9ee9631b40e6", + "zh:9b18fd51e260b2f3100937c34feae5f6fe3515df9b5e27ae23d00af75249a6d4", + "zh:a7154cdce28aeb80e822a97c6bc8b8acb7a074304fd198e265ac9cbcbda0ca06", + "zh:b0ce2ca42f018e5235a2171cdd8ba9829c90c54a6b2d602bd38e0e90c43d5d5d", + "zh:c67609f7018fc6e48b17befd6eeb21197e8f524496185c5e29707efa6967a0a5", + "zh:d4c9dc9d2a5a535851fc10049506bad1e7ab88193d5dcd371f91ac1b84f43a0a", + "zh:da27f2a9b9d5a4c02ec3893a763874513825c7c4dc2bb870ba741cf7725bcf9f", + "zh:e5bc1797b97607ff3d841c6c0d40da89c3843156ad43e15ded7d41fc0ac27717", + ] +} diff --git a/terraform/node.tf b/terraform/node.tf new file mode 100644 index 0000000..b7de91e --- /dev/null +++ b/terraform/node.tf @@ -0,0 +1,125 @@ +locals { + nodes_with_names = { + for k, v in var.nodes : k => merge(v, { + id = 700 + index(keys(var.nodes), k) + hash = sha1(v.name) + }) + } + nodes = { + for k, v in local.nodes_with_names : k => merge(v, { + mac_address = "AA:BB:07:00:${format("%v:%v", substr(v.hash, 0, 2), substr(v.hash, 2, 2))}" + }) + } + + + ipv4_addresses = { + for key, node in local.nodes : key => { + for k, v in proxmox_virtual_environment_vm.nodes[key].ipv4_addresses : + proxmox_virtual_environment_vm.nodes[key].network_interface_names[k] => v + } + } + ipv6_addresses = { + for key, node in local.nodes : key => { + for k, v in proxmox_virtual_environment_vm.nodes[key].ipv6_addresses : + proxmox_virtual_environment_vm.nodes[key].network_interface_names[k] => v + } + } + + nodes_with_address = { + for k, v in local.nodes : + k => merge(v, { + ipv4 = local.ipv4_addresses[k]["eth0"][0] + ipv6 = local.ipv6_addresses[k]["eth0"][0] + }) + } +} + +resource "proxmox_virtual_environment_file" "ingress" { + content_type = "iso" + datastore_id = var.common_storage + node_name = values(var.nodes)[0].host + + source_file { + path = var.image_path + file_name = "ingress-tjo-cloud.img" + } +} + +resource "proxmox_virtual_environment_file" "cloudinit" { + for_each = local.nodes + + node_name = each.value.host + content_type = "snippets" + datastore_id = var.common_storage + + source_raw { + data = <<-EOF + + EOF + file_name = "${each.value.name}-ingress-tjo-cloud.cloudinit.yaml" + } +} + +resource "proxmox_virtual_environment_vm" "nodes" { + for_each = local.nodes + + vm_id = each.value.id + name = each.value.name + node_name = each.value.host + + description = "Node ${each.value.name} for ingress.tjo.cloud." + tags = concat( + ["tjo-space"], + [each.value.name] + ) + + stop_on_destroy = true + timeout_start_vm = 60 + timeout_stop_vm = 60 + timeout_shutdown_vm = 60 + timeout_reboot = 60 + timeout_create = 120 + + cpu { + cores = each.value.cores + type = "host" + } + memory { + dedicated = each.value.memory + } + + operating_system { + type = "l26" + } + + agent { + enabled = true + timeout = "1m" + } + + network_device { + bridge = each.value.bridge + mac_address = each.value.mac_address + } + + cdrom { + enabled = true + file_id = proxmox_virtual_environment_file.ingress.id + } + + scsi_hardware = "virtio-scsi-single" + disk { + file_format = "raw" + interface = "virtio0" + datastore_id = each.value.storage + size = each.value.boot_size + backup = true + cache = "none" + iothread = true + } + + initialization { + datastore_id = each.value.storage + meta_data_file_id = proxmox_virtual_environment_file.cloudinit[each.key].id + } +} diff --git a/terraform/nodes.tf b/terraform/nodes.tf new file mode 100644 index 0000000..40e7713 --- /dev/null +++ b/terraform/nodes.tf @@ -0,0 +1,28 @@ + +locals { + locations = { + DE = ["46.4.88.62", "2a01:4f8:202:2395::"] + SI = ["93.103.125.118", "2a01:261:455:6c00:21e:6ff:fe45:c34"] + } +} + +data "digitalocean_domain" "ingress" { + name = "ingress.tjo.cloud" +} + +resource "digitalocean_record" "locations" { + for_each = merge([ + for location, ips in local.locations : { + for ip in ips : "${location} at ${ip}" => { + location = location, + ip = ip, + } + } + ]...) + + domain = data.digitalocean_domain.ingress.id + type = strcontains(each.value.ip, ":") ? "AAAA" : "A" + name = lower(each.value.location) + value = each.value.ip + ttl = 60 +} diff --git a/terraform/records.tf b/terraform/records.tf new file mode 100644 index 0000000..5221de4 --- /dev/null +++ b/terraform/records.tf @@ -0,0 +1,35 @@ +locals { + listeners = [ + { + domain = "k8s.tjo.cloud" + name = "api" + locations = ["SI", "DE"] + }, + { + domain = "k8s.tjo.cloud" + name = "dashboard" + locations = ["SI", "DE"] + } + ] +} + +resource "digitalocean_record" "listeners" { + for_each = merge(flatten([ + for listener in local.listeners : + [ + for location in listener.locations : { + for ip in local.locations[location] : "${ip} for ${listener.name}.${listener.domain} at ${location}" => { + ip = ip + domain = listener.domain + name = listener.name + } + } + ] + ])...) + + domain = each.value.domain + type = strcontains(each.value.ip, ":") ? "AAAA" : "A" + name = each.value.name + value = each.value.ip + ttl = 60 +} diff --git a/terraform/terraform.tf b/terraform/terraform.tf new file mode 100644 index 0000000..88a9394 --- /dev/null +++ b/terraform/terraform.tf @@ -0,0 +1,38 @@ +terraform { + required_providers { + digitalocean = { + source = "digitalocean/digitalocean" + version = "~> 2.0" + } + dns = { + source = "hashicorp/dns" + version = "~> 3.4.1" + } + proxmox = { + source = "bpg/proxmox" + version = "0.61.1" + } + tailscale = { + source = "tailscale/tailscale" + version = "0.16.1" + } + } + + required_version = "~> 1.7.3" +} + +provider "digitalocean" { + token = var.digitalocean_token +} + + +provider "proxmox" { + # FIXME: Traefik/NGINX breaks this! 500 ERROR + endpoint = "https://178.63.49.225:8006/api2/json" + insecure = true + api_token = var.proxmox_token + ssh { + agent = true + username = "root" + } +} diff --git a/terraform/variables.tf b/terraform/variables.tf new file mode 100644 index 0000000..fae3d30 --- /dev/null +++ b/terraform/variables.tf @@ -0,0 +1,32 @@ +variable "nodes" { + type = map(object({ + name = string + + host = string + bridge = string + + cores = optional(number, 1) + memory = optional(number, 512) + + storage = optional(string, "main") + boot_size = optional(number, 8) + + cloudinit = string + })) +} + +variable "common_storage" { + type = string +} + +variable "digitalocean_token" { + type = string +} + +variable "proxmox_token" { + type = string +} + +variable "image_path" { + type = string +}