Can NixOS Modules Be Tested In‑Place Without Production Secrets?
0 reputation · 28 Jul 2022, 03:29 UTC
0 reputation · 28 Jul 2022, 03:29 UTC
Validate that a NixOS module can be applied and verified in a sandbox that references only local configuration files, avoiding any production credential store.
• The test environment must not read from /etc/nixos/secrets or any external secret backend.
• Flake support may be enabled or disabled depending on the running NixOS version.
• Service activation may require a reboot; skipping it could leave stale state.
configuration.nix snippet is sufficient to trigger the module under test without pulling in external secrets?nixos-rebuild switch guarantee that service status is fully up‑to‑date without a reboot?35275 reputation · 28 Jul 2022, 13:17 UTC
Yes. A NixOS module can be applied and validated in a sandbox that references only local configuration files, provided you import only the module under test, supply dummy values for any secret‑backed options, and avoid importing /etc/nixos/secrets or external secret backends.
configuration.nix Snippet{ config, pkgs, ... }:
{
imports = [ ./module-under-test.nix ];
# Required boilerplate so the evaluator does not fall back to host config
networking.hostName = "test-host";
networking.hostId = "00000000";
boot.loader.grub.enable = false;
fileSystems."/" = { device = "none"; fsType = "tmpfs"; };
# Enable the module and stub every option that would read a secret file
services.myModule = {
enable = true;
# Replace secret‑backed options with inline dummy values
configFile = "";
apiKey = "test-key";
# If the module expects a path, point it at a local stub file
secretPath = ./stubs/secret.txt;
};
}
Place this file alongside module-under-test.nix and a stubs/ directory containing any placeholder files the module reads at evaluation time. Do not copy production secrets into the stub directory; doing so would violate the no‑production‑secrets constraint and could leak credentials into the Nix store.
nixos-rebuild switch builds the new system generation, updates the bootloader (if enabled), and activates systemd units via systemctl daemon-reload plus start/restart for changed units. It does not guarantee that every service reflects the new configuration without a reboot when:
ExecStartPre scripts, Type=notify changes).For modules that only manage user‑space daemons with standard systemd reload semantics, switch is usually sufficient. When in doubt, run systemctl status <unit> and journalctl -u <unit> after the switch; if the unit shows stale state, restart it manually or reboot.
| Aspect | Classic (nixos-rebuild switch) | Flake (nixos-rebuild switch --flake .#host) |
|---|---|---|
| Input source | Channel or NIX_PATH (mutable) | Locked flake.lock (immutable) |
| Determinism | Can drift when channels update | Reproducible as long as lockfile is unchanged |
| Secret handling | Same risk: any import /etc/nixos/secrets pulls production data | Same risk: flakes do not auto‑sanitize secret imports |
| CLI availability | All NixOS versions | Requires Nix 2.4+ with nix-command and flakes experimental features enabled |
For test determinism, prefer the flake path with a pinned nixpkgs input. If the target environment lacks flake support, pin a specific channel revision (e.g., nixos-24.11) via NIX_PATH to achieve comparable stability.
grep -r "/etc/nixos/secrets" . — confirm no production secret references exist in the test tree.nixos-rebuild build --flake .#test-host (or classic nixos-rebuild build) and inspect the generated unit files under ./result/systemd-units/ or /run/current-system/system/ after activation.switch, then systemctl status <your-module-service> and journalctl -u <your-module-service> -n 50.systemctl restart <your-module-service>; reboot only if the module touches bootloader, kernel, initrd, or early‑boot units.--flake (using a pinned nixpkgs for classic) and compare nix show-derivation outputs to confirm deterministic results.Does the module under test read secret files at evaluation time (inside the Nix expression) or only at runtime (via a systemd EnvironmentFile or similar)? Evaluation‑time reads will cause the build to fail unless you provide stub files; runtime reads can be satisfied with dummy unit overrides. This distinction changes whether you need stub files in ./stubs/ or can rely solely on inline option overrides.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 28 Jul 2022, 14:22 UTC
Assuming NixOS 24.05 with flake support optional, create a minimal configuration.nix that only imports the module under test and defines a dummy service, e.g. { config, pkgs, ... }: { imports = [ ./my-module.nix ]; services = { test = { enable = true; } }; } then run nixos-rebuild switch --flake inside a nix develop sandbox. The switch applies instantly and restarts affected services, but any change affecting the kernel or file system layout still requires a reboot to be fully up‑to‑date; verify with systemctl is-active and inspect the store path for secret references.