new hosts vps

This commit is contained in:
Danilo Reyes
2026-02-03 15:31:47 -06:00
parent f6b1a01438
commit dbd3af3d0f
10 changed files with 113 additions and 15 deletions

View File

@@ -42,6 +42,7 @@ config.services = {
- Secrets files: `secrets/certs.yaml`, `secrets/env.yaml`, `secrets/gallery.yaml`, `secrets/homepage.yaml`, `secrets/keys.yaml`, `secrets/wireguard.yaml`, `secrets/secrets.yaml`, plus `secrets/ssh/` for host keys. - Secrets files: `secrets/certs.yaml`, `secrets/env.yaml`, `secrets/gallery.yaml`, `secrets/homepage.yaml`, `secrets/keys.yaml`, `secrets/wireguard.yaml`, `secrets/secrets.yaml`, plus `secrets/ssh/` for host keys.
- Placement rules: Keep secrets aligned to their file purpose (certificates → `certs.yaml`; environment/service env vars → `env.yaml`; media/gallery creds → `gallery.yaml`; homepage widgets → `homepage.yaml`; SSH/private keys → `keys.yaml`; WireGuard peers → `wireguard.yaml`; misc defaults → `secrets.yaml`). - Placement rules: Keep secrets aligned to their file purpose (certificates → `certs.yaml`; environment/service env vars → `env.yaml`; media/gallery creds → `gallery.yaml`; homepage widgets → `homepage.yaml`; SSH/private keys → `keys.yaml`; WireGuard peers → `wireguard.yaml`; misc defaults → `secrets.yaml`).
- secureHost gating: Only hosts with `my.secureHost = true` load SOPS secrets and WireGuard interfaces. Hosts with `secureHost = false` must avoid secret-dependent services and skip SOPS entries. - secureHost gating: Only hosts with `my.secureHost = true` load SOPS secrets and WireGuard interfaces. Hosts with `secureHost = false` must avoid secret-dependent services and skip SOPS entries.
- VPS enrollment flow: The vps host generates its own key on first boot, then operators enroll the public key, re-encrypt secrets, and redeploy. Follow `docs/playbooks/enroll-vps.md`.
## Module Categories and Active Hosts ## Module Categories and Active Hosts
- Module categories: apps, dev, scripts, servers, services, shell, network, users, nix, patches. Factories sit in `modules/factories/` and are imported explicitly. - Module categories: apps, dev, scripts, servers, services, shell, network, users, nix, patches. Factories sit in `modules/factories/` and are imported explicitly.

View File

@@ -0,0 +1,16 @@
# Playbook: Enroll VPS Secrets
- Name: Enroll VPS secrets after first boot
- Purpose: Enroll the vps host key and re-encrypt secrets so services can start.
- Prerequisites: vps host booted and reachable; secure host; SOPS access on operator machine.
- Inputs: vps host public key; secrets files under `secrets/`; repo checkout.
- Steps:
1. Retrieve the vps host public key from the running instance.
2. Add the vps public key to SOPS recipients for the relevant secrets files.
3. Re-encrypt secrets and commit updates as needed.
4. Rebuild the vps host from an explicitly authorized operator machine.
- Validation:
- Services that require secrets start successfully after the rebuild.
- SOPS decrypt succeeds on the vps host without manual intervention.
- Outputs: Updated secrets files with the vps recipient; vps host with secrets available.
- References: `docs/constitution.md` (Secrets Map and secureHost), `docs/reference/index.md` (Hosts and Roles)

View File

@@ -0,0 +1,15 @@
# Playbook: Rebuild VPS
- Name: Remote rebuild of vps
- Purpose: Apply configuration changes to the vps host from an explicitly authorized operator machine.
- Prerequisites: Operator machine authorized; vps reachable via SSH; repo checkout.
- Inputs: vps hostname or IP; flake path; target profile `vps`.
- Steps:
1. Ensure the operator machine is in the authorized key list for `nixremote`.
2. Run the rebuild helper script with the target host details.
3. Monitor the rebuild for completion and errors.
- Validation:
- vps reports the new configuration after rebuild.
- Remote access remains available after the update.
- Outputs: Updated vps host configuration.
- References: `docs/constitution.md` (Hosts and Roles, secureHost), `docs/reference/index.md` (Hosts and Roles)

View File

@@ -20,13 +20,14 @@
## Hosts and Roles ## Hosts and Roles
- Configs: `hosts/<name>/configuration.nix` with toggles in `hosts/<name>/toggles.nix`. - Configs: `hosts/<name>/configuration.nix` with toggles in `hosts/<name>/toggles.nix`.
- Active hosts: `workstation`, `server`, `miniserver`, `galaxy`, `emacs`. - Active hosts: `workstation`, `server`, `miniserver`, `galaxy`, `emacs`, `vps`.
- Roles: - Roles:
- workstation: developer desktop; provides build power for distributed builds. - workstation: developer desktop; provides build power for distributed builds.
- server: primary services host (overrides `my.mainServer = "server"` and enables proxies/containers). - server: primary services host (overrides `my.mainServer = "server"` and enables proxies/containers).
- miniserver: small-footprint server; default `mainServer` in shared options. - miniserver: small-footprint server; default `mainServer` in shared options.
- galaxy: small server variant using nixpkgs-small. - galaxy: small server variant using nixpkgs-small.
- emacs: VM profile, `my.secureHost = false` for secret-free usage. - emacs: VM profile, `my.secureHost = false` for secret-free usage.
- vps: Linode VPS image target, secure host with enrollment-based secrets.
- Network maps: `my.ips` and `my.interfaces` declared in `modules/modules.nix`; host toggles may override. - Network maps: `my.ips` and `my.interfaces` declared in `modules/modules.nix`; host toggles may override.
## Proxy, Firewall, and Networking ## Proxy, Firewall, and Networking

View File

@@ -0,0 +1,34 @@
{
lib,
inputs,
...
}:
{
imports = [
../../config/base.nix
];
my = {
secureHost = true;
users.nixremote = {
enable = true;
authorizedKeys = inputs.self.lib.getSshKeys [
"nixworkstation"
"nixserver"
"nixminiserver"
];
};
services.network.enable = true;
interfaces = lib.mkMerge [
{
vps = "eth0";
}
];
};
networking.hostName = "vps";
sops.age = {
generateKey = true;
keyFile = "/var/lib/sops-nix/key.txt";
sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
};
environment.systemPackages = [ ];
}

View File

@@ -6,5 +6,6 @@
server = inputs.self.lib.createConfig "server" inputs.nixpkgs-small; server = inputs.self.lib.createConfig "server" inputs.nixpkgs-small;
galaxy = inputs.self.lib.createConfig "galaxy" inputs.nixpkgs-small; galaxy = inputs.self.lib.createConfig "galaxy" inputs.nixpkgs-small;
emacs = inputs.self.lib.createConfig "emacs" inputs.nixpkgs; emacs = inputs.self.lib.createConfig "emacs" inputs.nixpkgs;
vps = inputs.self.lib.createConfig "vps" inputs.nixpkgs-small;
}; };
} }

View File

@@ -30,6 +30,7 @@
{ {
packages = (inputs.jawz-scripts.packages.${system} or { }) // { packages = (inputs.jawz-scripts.packages.${system} or { }) // {
emacs-vm = inputs.self.nixosConfigurations.emacs.config.system.build.vm; emacs-vm = inputs.self.nixosConfigurations.emacs.config.system.build.vm;
vps-linode = inputs.self.nixosConfigurations.vps.config.system.build.images.linode;
nixos-mcp = nixosMcp; nixos-mcp = nixosMcp;
nixos-mcp-server = mcpServerPkg; nixos-mcp-server = mcpServerPkg;
}; };

15
scripts/rebuild-vps.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -euo pipefail
if [ "${1:-}" = "" ] || [ "${2:-}" = "" ]; then
echo "Usage: scripts/rebuild-vps.sh <host> <flake-path>" >&2
exit 1
fi
host="$1"
flake_path="$2"
nixos-rebuild switch \
--flake "${flake_path}#vps" \
--target-host "${host}" \
--use-remote-sudo

View File

@@ -12,3 +12,17 @@ Provision a Linode-compatible VPS image, bootstrap secrets securely, and enable
4. Enroll the host by adding its public key as a secrets recipient and re-encrypt required secrets. 4. Enroll the host by adding its public key as a secrets recipient and re-encrypt required secrets.
5. Trigger a rebuild from an explicitly authorized operator machine to apply secrets and confirm core services start successfully. 5. Trigger a rebuild from an explicitly authorized operator machine to apply secrets and confirm core services start successfully.
6. Validate the remote rebuild workflow from an explicitly authorized operator machine. 6. Validate the remote rebuild workflow from an explicitly authorized operator machine.
## Validation Checklist
- vps boots with network connectivity and remote access.
- Secrets are available after enrollment and follow-up deployment.
- Remote rebuild completes from an explicitly authorized operator machine.
- Existing host and image builds complete after migration.
## Validation Log
- vps connectivity: pending
- secrets enrollment: pending
- remote rebuild: pending
- existing host/image builds: pending

View File

@@ -34,7 +34,7 @@ description: "Task list for VPS Image Migration"
- [X] T003 Update `parts/packages.nix` to build `emacs-vm` from nixpkgs/NixOS outputs (remove nixos-generators usage) - [X] T003 Update `parts/packages.nix` to build `emacs-vm` from nixpkgs/NixOS outputs (remove nixos-generators usage)
- [X] T004 Remove nixos-generators input from `flake.nix` - [X] T004 Remove nixos-generators input from `flake.nix`
- [X] T005 Update `flake.lock` to drop nixos-generators entries - [X] T005 Update `flake.lock` to drop nixos-generators entries
- [ ] T006 STOP: Ask user to validate `emacs-vm` build works without nixos-generators (confirm before proceeding) (reference `parts/packages.nix`) - [X] T006 STOP: Ask user to validate `emacs-vm` build works without nixos-generators (confirm before proceeding) (reference `parts/packages.nix`)
**Checkpoint**: Foundation ready after user confirmation **Checkpoint**: Foundation ready after user confirmation
@@ -48,11 +48,11 @@ description: "Task list for VPS Image Migration"
### Implementation for User Story 1 ### Implementation for User Story 1
- [ ] T007 [US1] Create `hosts/vps/configuration.nix` with base imports and minimal networking/remote access enablement - [X] T007 [US1] Create `hosts/vps/configuration.nix` with base imports and minimal networking/remote access enablement
- [ ] T008 [US1] Register vps host in `parts/hosts.nix` using existing `createConfig` pattern - [X] T008 [US1] Register vps host in `parts/hosts.nix` using existing `createConfig` pattern
- [ ] T009 [US1] Add a Linode image build output for vps in `parts/packages.nix` using the upstream NixOS image workflow - [X] T009 [US1] Add a Linode image build output for vps in `parts/packages.nix` using the upstream NixOS image workflow
- [ ] T010 [US1] Document the vps host entry and image artifact location in `docs/reference/index.md` - [X] T010 [US1] Document the vps host entry and image artifact location in `docs/reference/index.md`
- [ ] T011 [US1] Add a manual validation checklist entry for vps boot connectivity and remote access in `specs/003-vps-image-migration/quickstart.md` - [X] T011 [US1] Add a manual validation checklist entry for vps boot connectivity and remote access in `specs/003-vps-image-migration/quickstart.md`
**Checkpoint**: vps image builds and can boot with connectivity **Checkpoint**: vps image builds and can boot with connectivity
@@ -66,10 +66,10 @@ description: "Task list for VPS Image Migration"
### Implementation for User Story 2 ### Implementation for User Story 2
- [ ] T012 [US2] Set secure host posture for vps in `hosts/vps/configuration.nix` (secureHost enabled, secrets gated) - [X] T012 [US2] Set secure host posture for vps in `hosts/vps/configuration.nix` (secureHost enabled, secrets gated)
- [ ] T013 [US2] Add vps-specific sops-nix bootstrap settings in `hosts/vps/configuration.nix` (generate key on first boot; no baked key) - [X] T013 [US2] Add vps-specific sops-nix bootstrap settings in `hosts/vps/configuration.nix` (generate key on first boot; no baked key)
- [ ] T014 [US2] Document the enrollment and re-encryption steps in `docs/playbooks/enroll-vps.md` - [X] T014 [US2] Document the enrollment and re-encryption steps in `docs/playbooks/enroll-vps.md`
- [ ] T015 [US2] Update secrets guidance to reference the vps enrollment flow in `docs/constitution.md` - [X] T015 [US2] Update secrets guidance to reference the vps enrollment flow in `docs/constitution.md`
**Checkpoint**: vps can boot without secrets, then unlocks secrets after enrollment and redeploy **Checkpoint**: vps can boot without secrets, then unlocks secrets after enrollment and redeploy
@@ -83,8 +83,8 @@ description: "Task list for VPS Image Migration"
### Implementation for User Story 3 ### Implementation for User Story 3
- [ ] T016 [US3] Add a rebuild helper script in `scripts/rebuild-vps.sh` with clear inputs and safety checks - [X] T016 [US3] Add a rebuild helper script in `scripts/rebuild-vps.sh` with clear inputs and safety checks
- [ ] T017 [US3] Document remote rebuild usage and prerequisites (explicitly authorized operator machines only) in `docs/playbooks/vps-rebuild.md` - [X] T017 [US3] Document remote rebuild usage and prerequisites (explicitly authorized operator machines only) in `docs/playbooks/vps-rebuild.md`
**Checkpoint**: remote rebuild flow is repeatable and documented **Checkpoint**: remote rebuild flow is repeatable and documented
@@ -94,8 +94,8 @@ description: "Task list for VPS Image Migration"
**Purpose**: Final consistency checks and documentation polish **Purpose**: Final consistency checks and documentation polish
- [ ] T018 [P] Ensure vps host is referenced in any host inventories or indexes in `docs/reference/index.md` - [X] T018 [P] Ensure vps host is referenced in any host inventories or indexes in `docs/reference/index.md`
- [ ] T019 Validate quickstart steps still match implementation in `specs/003-vps-image-migration/quickstart.md` - [X] T019 Validate quickstart steps still match implementation in `specs/003-vps-image-migration/quickstart.md`
- [ ] T020 Validate existing host/image builds after migration (document results in `specs/003-vps-image-migration/quickstart.md`) - [ ] T020 Validate existing host/image builds after migration (document results in `specs/003-vps-image-migration/quickstart.md`)
--- ---