diff --git a/infra/production/hetzner/helsinki/compute/.terraform.lock.hcl b/infra/production/hetzner/helsinki/compute/.terraform.lock.hcl index 99e0447..b24f626 100644 --- a/infra/production/hetzner/helsinki/compute/.terraform.lock.hcl +++ b/infra/production/hetzner/helsinki/compute/.terraform.lock.hcl @@ -1,6 +1,40 @@ # This file is maintained automatically by "tofu init". # Manual edits may be lost in future updates. +provider "registry.opentofu.org/hashicorp/external" { + version = "2.3.5" + hashes = [ + "h1:jcVmeuuz74tdRt2kj0MpUG9AORdlAlRRQ3k61y0r5Vc=", + "zh:1fb9aca1f068374a09d438dba84c9d8ba5915d24934a72b6ef66ef6818329151", + "zh:3eab30e4fcc76369deffb185b4d225999fc82d2eaaa6484d3b3164a4ed0f7c49", + "zh:4f8b7a4832a68080f0bf4f155b56a691832d8a91ce8096dac0f13a90081abc50", + "zh:5ff1935612db62e48e4fe6cfb83dfac401b506a5b7b38342217616fbcab70ce0", + "zh:993192234d327ec86726041eb6d1efb001e41f32e4518ad8b9b162130b65ee9a", + "zh:ce445e68282a2c4b2d1f994a2730406df4ea47914c0932fb4a7eb040a7ec7061", + "zh:e305e17216840c54194141fb852839c2cedd6b41abd70cf8d606d6e88ed40e64", + "zh:edba65fb241d663c09aa2cbf75026c840e963d5195f27000f216829e49811437", + "zh:f306cc6f6ec9beaf75bdcefaadb7b77af320b1f9b56d8f50df5ebd2189a93148", + "zh:fb2ff9e1f86796fda87e1f122d40568912a904da51d477461b850d81a0105f3d", + ] +} + +provider "registry.opentofu.org/hashicorp/null" { + version = "3.2.4" + hashes = [ + "h1:jsKjBiLb+v3OIC3xuDiY4sR0r1OHUMSWPYKult9MhT0=", + "zh:1769783386610bed8bb1e861a119fe25058be41895e3996d9216dd6bb8a7aee3", + "zh:32c62a9387ad0b861b5262b41c5e9ed6e940eda729c2a0e58100e6629af27ddb", + "zh:339bf8c2f9733fce068eb6d5612701144c752425cebeafab36563a16be460fb2", + "zh:36731f23343aee12a7e078067a98644c0126714c4fe9ac930eecb0f2361788c4", + "zh:3d106c7e32a929e2843f732625a582e562ff09120021e510a51a6f5d01175b8d", + "zh:74bcb3567708171ad83b234b92c9d63ab441ef882b770b0210c2b14fdbe3b1b6", + "zh:90b55bdbffa35df9204282251059e62c178b0ac7035958b93a647839643c0072", + "zh:ae24c0e5adc692b8f94cb23a000f91a316070fdc19418578dcf2134ff57cf447", + "zh:b5c10d4ad860c4c21273203d1de6d2f0286845edf1c64319fa2362df526b5f58", + "zh:e05bbd88e82e1d6234988c85db62fd66f11502645838fff594a2ec25352ecd80", + ] +} + provider "registry.opentofu.org/hetznercloud/hcloud" { version = "1.52.0" constraints = "~> 1.45" diff --git a/infra/production/hetzner/helsinki/compute/configuration.nix b/infra/production/hetzner/helsinki/compute/configuration.nix new file mode 100644 index 0000000..44e4b41 --- /dev/null +++ b/infra/production/hetzner/helsinki/compute/configuration.nix @@ -0,0 +1,118 @@ +{ pkgs, ... }: + +{ + disko.devices = { + disk = { + main = { + type = "disk"; + # TODO don't hard code device? + device = "/dev/sda"; + content = { + type = "gpt"; + partitions = { + boot = { + size = "1M"; + type = "EF02"; # for grub MBR + }; + ESP = { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; + }; + + boot = { + loader = { + systemd-boot = { + enable = true; + }; + efi = { + canTouchEfiVariables = true; + }; + }; + }; + + networking = { + networkmanager = { + enable = true; + }; + firewall = { + # https://docs.k3s.io/installation/requirements#inbound-rules-for-k3s-server-nodes + allowedTCPPorts = [ + 6443 + 10250 + ]; + allowedTCPPortRanges = [ + { from = 2379; to = 2380; } + ]; + }; + }; + + nix = { + settings = { + experimental-features = [ + "nix-command" + "flakes" + ]; + }; + optimise.automatic = true; + gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 30d"; + }; + }; + + services = { + openssh.enable = true; + k3s = { + enable = true; + role = "server"; + extraFlags = toString [ + "--disable-helm-controller" + "--disable-network-policy" + "--disable=traefik" + "--secrets-encryption=true" + "--snapshotter=stargz" + + # TODO better ipv6 ipam + "--cluster-cidr=2001:cafe:42::/56" + "--service-cidr=2001:cafe:43::/112" + ]; + }; + }; + + users.users.admin = { + isNormalUser = true; + description = "Admin"; + extraGroups = [ + "networkmanager" + "wheel" + ]; + packages = with pkgs; [ + neovim + git + gnumake + tmux + ]; + }; + + system.stateVersion = "25.05"; +} diff --git a/infra/production/hetzner/helsinki/compute/flake.lock b/infra/production/hetzner/helsinki/compute/flake.lock new file mode 100644 index 0000000..88d397f --- /dev/null +++ b/infra/production/hetzner/helsinki/compute/flake.lock @@ -0,0 +1,48 @@ +{ + "nodes": { + "disko": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1755519972, + "narHash": "sha256-bU4nqi3IpsUZJeyS8Jk85ytlX61i4b0KCxXX9YcOgVc=", + "owner": "nix-community", + "repo": "disko", + "rev": "4073ff2f481f9ef3501678ff479ed81402caae6d", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "disko", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1755593991, + "narHash": "sha256-BA9MuPjBDx/WnpTJ0EGhStyfE7hug8g85Y3Ju9oTsM4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a58390ab6f1aa810eb8e0f0fc74230e7cc06de03", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "disko": "disko", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/infra/production/hetzner/helsinki/compute/flake.nix b/infra/production/hetzner/helsinki/compute/flake.nix new file mode 100644 index 0000000..125ad6f --- /dev/null +++ b/infra/production/hetzner/helsinki/compute/flake.nix @@ -0,0 +1,21 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; + disko = { + url = "github:nix-community/disko"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { self, nixpkgs, disko }: { + nixosConfigurations = { + master = nixpkgs.lib.nixosSystem { + system = "aarch64-linux"; # TODO support multiple systems + modules = [ + disko.nixosModules.disko + ./configuration.nix + ]; + }; + }; + }; +} diff --git a/infra/production/hetzner/helsinki/compute/main.tf b/infra/production/hetzner/helsinki/compute/main.tf index db83c10..acb7d98 100644 --- a/infra/production/hetzner/helsinki/compute/main.tf +++ b/infra/production/hetzner/helsinki/compute/main.tf @@ -10,13 +10,29 @@ resource "hcloud_server" "nodes" { name = each.key server_type = "cax11" public_net { - ipv4_enabled = false + ipv4_enabled = true ipv6_enabled = true } - # TODO NixOS - image = "debian-13" + image = "debian-13" # Only used to bootstrap nixos-anywhere location = each.value.location ssh_keys = [ hcloud_ssh_key.main.id ] } + +module "nixos" { + for_each = hcloud_server.nodes + + source = "github.com/nix-community/nixos-anywhere//terraform/all-in-one" + nixos_system_attr = "${var.flake}#nixosConfigurations.master.config.system.build.toplevel" + nixos_partitioner_attr = "${var.flake}#nixosConfigurations.master.config.system.build.diskoScript" + target_host = each.value.ipv6_address + instance_id = each.value.name + build_on_remote = true + # extra_files_script = "${path.module}/decrypt-ssh-secrets.sh" + # disk_encryption_key_scripts = [{ + # path = "/tmp/secret.key" + # # script is below + # script = "${path.module}/decrypt-zfs-key.sh" + # }] +} diff --git a/infra/production/hetzner/helsinki/compute/terragrunt.hcl b/infra/production/hetzner/helsinki/compute/terragrunt.hcl index b40e7f1..8127cde 100644 --- a/infra/production/hetzner/helsinki/compute/terragrunt.hcl +++ b/infra/production/hetzner/helsinki/compute/terragrunt.hcl @@ -8,11 +8,12 @@ inputs = { "master-1" = { location = "hel1" } - "worker-1" = { - location = "nbg1" - } - "worker-2" = { - location = "fsn1" - } + # "worker-1" = { + # location = "nbg1" + # } + # "worker-2" = { + # location = "fsn1" + # } } + flake = get_terragrunt_dir() } diff --git a/infra/production/hetzner/helsinki/compute/variables.tf b/infra/production/hetzner/helsinki/compute/variables.tf index 4243e41..478afd7 100644 --- a/infra/production/hetzner/helsinki/compute/variables.tf +++ b/infra/production/hetzner/helsinki/compute/variables.tf @@ -3,3 +3,7 @@ variable "nodes" { location = string })) } + +variable "flake" { + +}