From 94feae82a083701493fe97b61dfec023dff126eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torjus=20H=C3=A5kestad?= Date: Sat, 7 Feb 2026 23:18:08 +0100 Subject: [PATCH] ns1: recreate with OpenTofu workflow Old VM had incorrect hardware-configuration.nix with hardcoded UUIDs that didn't match actual disk layout, causing boot failure (emergency mode). Recreated using template2-based configuration for OpenTofu provisioning. Co-Authored-By: Claude Opus 4.5 --- docs/plans/ns1-recreation.md | 107 +++++++++++++++++++++++++++ flake.nix | 18 ++--- hosts/ns1/configuration.nix | 35 +++++---- hosts/ns1/default.nix | 2 +- hosts/ns1/hardware-configuration.nix | 36 --------- terraform/vault/approle.tf | 6 -- terraform/vault/hosts-generated.tf | 5 ++ terraform/vms.tf | 7 ++ 8 files changed, 150 insertions(+), 66 deletions(-) create mode 100644 docs/plans/ns1-recreation.md delete mode 100644 hosts/ns1/hardware-configuration.nix diff --git a/docs/plans/ns1-recreation.md b/docs/plans/ns1-recreation.md new file mode 100644 index 0000000..c02fceb --- /dev/null +++ b/docs/plans/ns1-recreation.md @@ -0,0 +1,107 @@ +# ns1 Recreation Plan + +## Overview + +Recreate ns1 using the OpenTofu workflow after the existing VM entered emergency mode due to incorrect hardware-configuration.nix (hardcoded UUIDs that don't match actual disk layout). + +## Current ns1 Configuration to Preserve + +- **IP:** 10.69.13.5/24 +- **Gateway:** 10.69.13.1 +- **Role:** Primary DNS (authoritative + resolver) +- **Services:** + - `../../services/ns/master-authorative.nix` + - `../../services/ns/resolver.nix` +- **Metadata:** + - `homelab.host.role = "dns"` + - `homelab.host.labels.dns_role = "primary"` +- **Vault:** enabled +- **Deploy:** enabled + +## Execution Steps + +### Phase 1: Remove Old Configuration + +```bash +nix develop -c create-host --remove --hostname ns1 --force +``` + +This removes: +- `hosts/ns1/` directory +- Entry from `flake.nix` +- Any terraform entries (none exist currently) + +### Phase 2: Create New Configuration + +```bash +nix develop -c create-host --hostname ns1 --ip 10.69.13.5/24 +``` + +This creates: +- `hosts/ns1/` with template2-based configuration +- Entry in `flake.nix` +- Entry in `terraform/vms.tf` +- Vault wrapped token for bootstrap + +### Phase 3: Customize Configuration + +After create-host, manually update `hosts/ns1/configuration.nix` to add: + +1. DNS service imports: + ```nix + ../../services/ns/master-authorative.nix + ../../services/ns/resolver.nix + ``` + +2. Host metadata: + ```nix + homelab.host = { + tier = "prod"; + role = "dns"; + labels.dns_role = "primary"; + }; + ``` + +3. Disable resolved (conflicts with Unbound): + ```nix + services.resolved.enable = false; + ``` + +### Phase 4: Commit Changes + +```bash +git add -A +git commit -m "ns1: recreate with OpenTofu workflow + +Old VM had incorrect hardware-configuration.nix with hardcoded UUIDs +that didn't match actual disk layout, causing boot failure. + +Recreated using template2-based configuration for OpenTofu provisioning." +``` + +### Phase 5: Infrastructure + +1. Delete old ns1 VM in Proxmox (it's broken anyway) +2. Run `nix develop -c tofu -chdir=terraform apply` +3. Wait for bootstrap to complete +4. Verify ns1 is functional: + - DNS resolution working + - Zone transfer to ns2 working + - All exporters responding + +### Phase 6: Finalize + +- Push to master +- Move this plan to `docs/plans/completed/` + +## Rollback + +If the new VM fails: +1. ns2 is still operational as secondary DNS +2. Can recreate with different settings if needed + +## Notes + +- ns2 will continue serving DNS during the migration +- Zone data is generated from flake, so no data loss +- The old VM's disk can be kept briefly in Proxmox as backup if desired diff --git a/flake.nix b/flake.nix index fcda061..7640da0 100644 --- a/flake.nix +++ b/flake.nix @@ -65,15 +65,6 @@ in { nixosConfigurations = { - ns1 = nixpkgs.lib.nixosSystem { - inherit system; - specialArgs = { - inherit inputs self; - }; - modules = commonModules ++ [ - ./hosts/ns1 - ]; - }; ha1 = nixpkgs.lib.nixosSystem { inherit system; specialArgs = { @@ -182,6 +173,15 @@ ./hosts/ns2 ]; }; + ns1 = nixpkgs.lib.nixosSystem { + inherit system; + specialArgs = { + inherit inputs self; + }; + modules = commonModules ++ [ + ./hosts/ns1 + ]; + }; }; packages = forAllSystems ( { pkgs }: diff --git a/hosts/ns1/configuration.nix b/hosts/ns1/configuration.nix index dd504d4..130d803 100644 --- a/hosts/ns1/configuration.nix +++ b/hosts/ns1/configuration.nix @@ -7,23 +7,38 @@ { imports = [ - ./hardware-configuration.nix + ../template2/hardware-configuration.nix ../../system + ../../common/vm + + # DNS services ../../services/ns/master-authorative.nix ../../services/ns/resolver.nix - ../../common/vm ]; + # Host metadata + homelab.host = { + tier = "prod"; + role = "dns"; + labels.dns_role = "primary"; + }; + + # Enable Vault integration + vault.enable = true; + + # Enable remote deployment via NATS + homelab.deploy.enable = true; + nixpkgs.config.allowUnfree = true; - # Use the systemd-boot EFI boot loader. boot.loader.grub.enable = true; - boot.loader.grub.device = "/dev/sda"; + boot.loader.grub.device = "/dev/vda"; networking.hostName = "ns1"; networking.domain = "home.2rjus.net"; networking.useNetworkd = true; networking.useDHCP = false; + # Disable resolved - conflicts with Unbound resolver services.resolved.enable = false; networking.nameservers = [ "10.69.13.5" @@ -47,14 +62,6 @@ "nix-command" "flakes" ]; - vault.enable = true; - homelab.deploy.enable = true; - - homelab.host = { - role = "dns"; - labels.dns_role = "primary"; - }; - nix.settings.tarball-ttl = 0; environment.systemPackages = with pkgs; [ vim @@ -68,5 +75,5 @@ # Or disable the firewall altogether. networking.firewall.enable = false; - system.stateVersion = "23.11"; # Did you read the comment? -} + system.stateVersion = "25.11"; # Did you read the comment? +} \ No newline at end of file diff --git a/hosts/ns1/default.nix b/hosts/ns1/default.nix index 4cd684a..57ed4b4 100644 --- a/hosts/ns1/default.nix +++ b/hosts/ns1/default.nix @@ -2,4 +2,4 @@ imports = [ ./configuration.nix ]; -} +} \ No newline at end of file diff --git a/hosts/ns1/hardware-configuration.nix b/hosts/ns1/hardware-configuration.nix deleted file mode 100644 index 881ea3c..0000000 --- a/hosts/ns1/hardware-configuration.nix +++ /dev/null @@ -1,36 +0,0 @@ -{ config, lib, pkgs, modulesPath, ... }: - -{ - imports = - [ - (modulesPath + "/profiles/qemu-guest.nix") - ]; - - boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ]; - boot.initrd.kernelModules = [ ]; - # boot.kernelModules = [ ]; - # boot.extraModulePackages = [ ]; - - fileSystems."/" = - { - device = "/dev/disk/by-uuid/6889aba9-61ed-4687-ab10-e5cf4017ac8d"; - fsType = "xfs"; - }; - - fileSystems."/boot" = - { - device = "/dev/disk/by-uuid/BC07-3B7A"; - fsType = "vfat"; - }; - - swapDevices = - [{ device = "/dev/disk/by-uuid/64e5757b-6625-4dd2-aa2a-66ca93444d23"; }]; - - # Enables DHCP on each ethernet and wireless interface. In case of scripted networking - # (the default) this is the recommended approach. When using systemd-networkd it's - # still possible to use this option, but it's recommended to use it in conjunction - # with explicit per-interface declarations with `networking.interfaces..useDHCP`. - # networking.interfaces.ens18.useDHCP = lib.mkDefault true; - - nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; -} diff --git a/terraform/vault/approle.tf b/terraform/vault/approle.tf index fd42093..acca017 100644 --- a/terraform/vault/approle.tf +++ b/terraform/vault/approle.tf @@ -67,12 +67,6 @@ locals { } # Wave 3: DNS servers - "ns1" = { - paths = [ - "secret/data/hosts/ns1/*", - "secret/data/shared/dns/*", - ] - } # Wave 4: http-proxy "http-proxy" = { diff --git a/terraform/vault/hosts-generated.tf b/terraform/vault/hosts-generated.tf index 6a45d20..f88ab67 100644 --- a/terraform/vault/hosts-generated.tf +++ b/terraform/vault/hosts-generated.tf @@ -26,6 +26,11 @@ locals { "secret/data/shared/dns/*", ] } + "ns1" = { + paths = [ + "secret/data/hosts/ns1/*", + ] + } } diff --git a/terraform/vms.tf b/terraform/vms.tf index e7a10fd..fdd47be 100644 --- a/terraform/vms.tf +++ b/terraform/vms.tf @@ -65,6 +65,13 @@ locals { disk_size = "20G" vault_wrapped_token = "s.3nran1e1Uim4B1OomIWCoS4T" } + "ns1" = { + ip = "10.69.13.5/24" + cpu_cores = 2 + memory = 2048 + disk_size = "20G" + vault_wrapped_token = "s.b6ge0KMtNQctdKkvm0RNxGdt" + } } # Compute VM configurations with defaults applied