diff --git a/infra/nixos/configuration.nix b/infra/nixos/configuration.nix new file mode 100644 index 0000000..eacdbd5 --- /dev/null +++ b/infra/nixos/configuration.nix @@ -0,0 +1,67 @@ +{ modulesPath, ... }: + +{ + imports = [ + (modulesPath + "/profiles/all-hardware.nix") + ]; + + boot = { + loader = { + systemd-boot = { + enable = true; + }; + efi = { + canTouchEfiVariables = true; + }; + }; + }; + + networking = { + networkmanager = { + enable = true; + }; + }; + + nix = { + settings = { + experimental-features = [ + "nix-command" + "flakes" + ]; + }; + optimise.automatic = true; + gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 30d"; + }; + }; + + services = { + openssh = { + enable = true; + }; + qemuGuest = { + enable = true; + }; + }; + + users.users = { + admin = { + isNormalUser = true; + extraGroups = [ + "wheel" + ]; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN5ue4np7cF34f6dwqH1262fPjkowHQ8irfjVC156PCG" + ]; + }; + root = { + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN5ue4np7cF34f6dwqH1262fPjkowHQ8irfjVC156PCG" + ]; + }; + }; + + system.stateVersion = "24.11"; +} diff --git a/infra/nixos/disks.nix b/infra/nixos/disks.nix new file mode 100644 index 0000000..1b66a29 --- /dev/null +++ b/infra/nixos/disks.nix @@ -0,0 +1,33 @@ +{ + disko.devices = { + disk = { + main = { + type = "disk"; + device = "/dev/sda"; + content = { + type = "gpt"; + partitions = { + ESP = { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/infra/nixos/flake.lock b/infra/nixos/flake.lock new file mode 100644 index 0000000..35c7766 --- /dev/null +++ b/infra/nixos/flake.lock @@ -0,0 +1,47 @@ +{ + "nodes": { + "disko": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1737038063, + "narHash": "sha256-rMEuiK69MDhjz1JgbaeQ9mBDXMJ2/P8vmOYRbFndXsk=", + "owner": "nix-community", + "repo": "disko", + "rev": "bf0abfde48f469c256f2b0f481c6281ff04a5db2", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "disko", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1737672001, + "narHash": "sha256-YnHJJ19wqmibLQdUeq9xzE6CjrMA568KN/lFPuSVs4I=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "035f8c0853c2977b24ffc4d0a42c74f00b182cd8", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-24.11", + "type": "indirect" + } + }, + "root": { + "inputs": { + "disko": "disko", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/infra/nixos/flake.nix b/infra/nixos/flake.nix new file mode 100644 index 0000000..36ffb41 --- /dev/null +++ b/infra/nixos/flake.nix @@ -0,0 +1,39 @@ +{ + inputs = { + nixpkgs.url = "nixpkgs/nixos-24.11"; + disko = { + url = "github:nix-community/disko"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + outputs = { nixpkgs, disko, ... }: { + nixosConfigurations = { + nixos = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + disko.nixosModules.disko + ./configuration.nix + ./disks.nix + ]; + }; + devbox = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + disko.nixosModules.disko + ./configuration.nix + ./disks.nix + ./profiles/devbox.nix + ]; + }; + k3s = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + disko.nixosModules.disko + ./configuration.nix + ./disks.nix + ./profiles/k3s.nix + ]; + }; + }; + }; +} diff --git a/infra/nixos/profiles/k3s.nix b/infra/nixos/profiles/k3s.nix new file mode 100644 index 0000000..0c49e0b --- /dev/null +++ b/infra/nixos/profiles/k3s.nix @@ -0,0 +1,28 @@ +{ pkgs, ... }: + +{ + networking = { + firewall = { + # https://docs.k3s.io/installation/requirements#inbound-rules-for-k3s-server-nodes + allowedTCPPorts = [ + 6443 + 10250 + ]; + allowedTCPPortRanges = [ + { from = 2379; to = 2380; } + ]; + }; + }; + + services = { + k3s = { + enable = true; + role = "server"; + extraFlags = toString [ + "--disable-helm-controller" + "--disable-network-policy" + "--disable=traefik" + ]; + }; + }; +} diff --git a/infra/production/proxmox/vn-southwest-1/compute/.terraform.lock.hcl b/infra/production/proxmox/vn-southwest-1/compute/.terraform.lock.hcl new file mode 100644 index 0000000..07c6e0d --- /dev/null +++ b/infra/production/proxmox/vn-southwest-1/compute/.terraform.lock.hcl @@ -0,0 +1,98 @@ +# This file is maintained automatically by "tofu init". +# Manual edits may be lost in future updates. + +provider "registry.opentofu.org/bpg/proxmox" { + version = "0.57.1" + constraints = "~> 0.57.0" + hashes = [ + "h1:F6o5o32V+mE96gHUppHI0U+olrEtxtr23fwUigtQ/Wk=", + "zh:220c75d76e8779970d4e01effdb3073a24139f5065397dae1347710e80b69865", + "zh:271d71cb39225a4efd4b6e0cbb2cba50f89006a353db932969deed5db07cdd9b", + "zh:28c4f33a1b888f488f1a557d21a1383eb9f9bff77d6ed0643b393c02135436bd", + "zh:2c468cb678cdd44f896b531fc09f7a68b16dde298bfded89ee94b792233ddbf1", + "zh:3329ce5f7bd96233cf75a633f9b0927295083cc365a4324294dc8bfbcd4bb2a3", + "zh:5d5c99f763488c30fbab66b6c68adac1f9d41b8439a7201d826351353c452470", + "zh:6a67c621b0bd8c54037ea93273d78308f0a7d2c8b5316def4245c58686639818", + "zh:8d64bbc24008d507608e53d1e9d09705710a07ba5b5fe3b5c5cce51ddd0fa6ac", + "zh:99395ff6c92d49033ba5426c0f3a07c893354883e86d9000692907150a3c096c", + "zh:b03996ae36df1181af784ed57267f8761092400018d40ae2649fa8ec9cabef96", + "zh:be6eb719192e228905a556e59d2814da2d26e512c9b0b2f04b224a7e80d2a017", + "zh:c3c1f9c94ad381a1e1d022f1d02bc446ea47563eb6573c40471c6b0e6293c20c", + "zh:cad37192fb69db274fa053564502077cedc7c8679373a3a8c35da91ed8988a19", + "zh:eabc19a8e0d287bb1abbde3d331fc5ca27943dae24cca8d8812b66fd9c8ed4d3", + "zh:f26e0763dbe6a6b2195c94b44696f2110f7f55433dc142839be16b9697fa5597", + ] +} + +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/hashicorp/oci" { + version = "7.15.0" + hashes = [ + "h1:qd075zUzmjgm+W3GezX95h9hjdFkKnCagDzy5RxUf28=", + "zh:2e198d561ab5dbcf84c1984050bbcf5691811aebb22a06af8d946666686ac86b", + "zh:33f242ca79e20069b54847477e8dbe28f965c7df3da05d0e1f31377dd9b24367", + "zh:3d7c961d4b012e5d63588d030e491adf9b980555a5ab3c4510e9b74887aa81ec", + "zh:44265b99500a7bb53e9c7108f0e83df5ebf480261388fc0a565e1785e6349da4", + "zh:478bdb9d0883e74bf7ea11e352dc1e36bdb21d40c887da56675ad8411f7e8fec", + "zh:5898c4ecb3e9f4ebd91a849e40e7925e73b5ef282afaf3f37069274817ebe886", + "zh:5d9c2345e7e25e4cb02c9e4f6ce283ef37c4220c76ac39f1c14b8c9a77905b93", + "zh:5e788eb84430d3872460df71e96c5b0363761a399c729581c13edfb327cbb67f", + "zh:710183628e249f094afcb452a22812d878ae3728b4541adf38e8006087711e96", + "zh:7ebb6d5586735e853d2c7ec6436dad945a72bb360e6a600c8c311d98d8819fda", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:c9e5b7f0dea6b1a6c1099b3bd64114382102b4dbe839c2dc53b3cd757f39bb4a", + "zh:da2889b73c573531e235fc351f0caec925512fddac864f68812a175779b4b654", + "zh:e12d11047fc78cace1b523791184bab6bf79d6d34fe82f56099313675f709c31", + "zh:fd41831a5f59ed347cf75813491a0894f97b87618efa0b1037e369c260e0446e", + ] +} + +provider "registry.opentofu.org/hashicorp/time" { + version = "0.13.1" + hashes = [ + "h1:ueilLAoXlZPufdJYuPFeqznwP39ZwLsRcQtqow+NUiI=", + "zh:10f32af8b544a039f19abd546e345d056a55cb7bdd69d5bbd7322cbc86883848", + "zh:35dd5beb34a9f73de8d0fed332814c69acae69397c9c065ce63ccd8315442bef", + "zh:56545d1dd5f2e7262e0c0c124264974229ec9cc234d0d7a0e36e14b869590f4a", + "zh:8d7259c3f819fd3470ff933c904b6a549502a8351feb1b5c040a4560decaf7e0", + "zh:a40f26878826b142e26fe193f7e3e14fc97f615cd6af140e88ce5bc25f3fcf50", + "zh:b2e82f25fecff172a9a9e24ea37d37e4fc630ee9245617cb40b10e66a6b979c8", + "zh:d4b699850a40ed07ef83c6b827605d24050b2732646ee017bda278e4ddf01c91", + "zh:e4e6a5e5614b6a54557400aabb748ebd57e947cdbd21ad1c7602c51368a80559", + "zh:eb78fb97bca22931e730487a20a90f5a6221ddfb3138aaf070737ea2b7c9c885", + "zh:faba366a1352ee679bba2a5b09c073c6854721db94b191d49b620b60946a065f", + ] +} diff --git a/infra/production/proxmox/vn-southwest-1/compute/nixos-vm/main.tf b/infra/production/proxmox/vn-southwest-1/compute/nixos-vm/main.tf new file mode 100644 index 0000000..a6a5317 --- /dev/null +++ b/infra/production/proxmox/vn-southwest-1/compute/nixos-vm/main.tf @@ -0,0 +1,69 @@ +resource "proxmox_virtual_environment_vm" "main" { + name = var.name + node_name = var.node_name + + cpu { + cores = var.cpu.cores + } + + memory { + dedicated = 1024 * var.memory.dedicated + # Set floating to the same value as dedicated to enable ballooning device + floating = 1024 * var.memory.dedicated + } + + cdrom { + enabled = true + file_id = "local:iso/${var.cdrom.file}" + interface = "ide3" + } + + dynamic "disk" { + for_each = var.disks + content { + datastore_id = "local-lvm" + interface = "scsi0" + size = disk.value.size + file_format = "raw" + } + } + + boot_order = [ + "scsi0", + "ide3", + ] + + bios = "ovmf" + + operating_system { + type = "l26" + } + + network_device { + bridge = "vmbr0" + } + + agent { + enabled = true + } + + tags = var.tags +} + +# Temporary hack to wait for IP addresses to be actually available +# https://github.com/bpg/terraform-provider-proxmox/issues/776 +resource "time_sleep" "wait_for_ip" { + depends_on = [proxmox_virtual_environment_vm.main] + + create_duration = "30s" +} + +module "main" { + source = "github.com/nix-community/nixos-anywhere//terraform/all-in-one?ref=1.6.0" + nixos_system_attr = "${var.nixos.flake}#nixosConfigurations.${var.nixos.host}.config.system.build.toplevel" + nixos_partitioner_attr = "${var.nixos.flake}#nixosConfigurations.${var.nixos.host}.config.system.build.diskoScript" + target_host = proxmox_virtual_environment_vm.main.ipv4_addresses[1][0] + instance_id = proxmox_virtual_environment_vm.main.id + + depends_on = [time_sleep.wait_for_ip] +} diff --git a/infra/production/proxmox/vn-southwest-1/compute/nixos-vm/terraform.tf b/infra/production/proxmox/vn-southwest-1/compute/nixos-vm/terraform.tf new file mode 100644 index 0000000..350f1c1 --- /dev/null +++ b/infra/production/proxmox/vn-southwest-1/compute/nixos-vm/terraform.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + proxmox = { + source = "bpg/proxmox" + version = "~> 0.57.0" + } + } +} diff --git a/infra/production/proxmox/vn-southwest-1/compute/nixos-vm/variables.tf b/infra/production/proxmox/vn-southwest-1/compute/nixos-vm/variables.tf new file mode 100644 index 0000000..8231cf1 --- /dev/null +++ b/infra/production/proxmox/vn-southwest-1/compute/nixos-vm/variables.tf @@ -0,0 +1,48 @@ +variable "name" { + type = string +} + +variable "node_name" { + type = string + default = "proxmox" +} + +variable "nixos" { + type = object({ + flake = string + host = string + }) +} + +variable "cpu" { + type = object({ + cores = number + }) +} + +variable "memory" { + type = object({ + dedicated = number + }) +} + +variable "cdrom" { + type = object({ + file = string + }) + + default = { + file = "nixos-24.11.20250123.035f8c0-x86_64-linux.iso" + } +} + +variable "disks" { + type = map(object({ + size = number + })) +} + +variable "tags" { + type = list(string) + default = [] +} diff --git a/infra/production/proxmox/vn-southwest-1/compute/terragrunt.hcl b/infra/production/proxmox/vn-southwest-1/compute/terragrunt.hcl new file mode 100644 index 0000000..6638eda --- /dev/null +++ b/infra/production/proxmox/vn-southwest-1/compute/terragrunt.hcl @@ -0,0 +1,27 @@ +include "root" { + path = find_in_parent_folders("root.hcl") + expose = true +} + +terraform { + source = "./nixos-vm" +} + +inputs = { + name = "k3s" + nixos = { + flake = "${get_terragrunt_dir()}/../../../../nixos" + host = "k3s" + } + cpu = { + cores = 8 + } + memory = { + dedicated = 16 + } + disks = { + os = { + size = 256 + } + } +} diff --git a/infra/production/root.hcl b/infra/production/root.hcl index 1f5c216..bf9f9db 100644 --- a/infra/production/root.hcl +++ b/infra/production/root.hcl @@ -44,6 +44,10 @@ generate "provider" { private_key = local.secrets.oracle_private_key region = local.secrets.oracle_region } + proxmox = { + endpoint = "https://proxmox:8006" + insecure = true + } } }) }