To expand on that answer, here’s a simple example of a flake.nix:
{
inputs.nixpkgs.url="github:NixOS/nixpkgs/23.05";
outputs = { self, nixpkgs, ... }: {
nixosConfigurations = nixpkgs.lib.genAttrs [ "alice" "bob" "chloe" ] (
user: nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
(import ./configuration.nix { inherit user; })
];
}
);
};
}
And the accompanying configuration.nix:
{ user }:
{ config, pkgs, ... }:
{
services.httpd.enable = true;
services.httpd.adminAddr = "${user}@example.org";
services.httpd.virtualHosts.localhost.documentRoot = "/webroot";
}
The configuration is not complete, but you get the idea. Instead of a regular function, configuration.nix is now a higher-order function that you can call with some arguments (in this case just user
) and it will return a new function where the user name has been inserted to the services.httpd.adminAddr
option.
The flake.nix file then, instead of just passing the configuration as a module directly, imports it and calls it with the username. nixpkgs.lib.genAttrs just takes the usernames and creates a separate output for each:
$ nix flake show
path:/Users/felix/repos/experiments/sysconf?lastModified=1687636645&narHash=sha256-963ttCohsJfEMsciNWnoB1dQxLh6ElnXSL/nDanr6qE%3D
└───nixosConfigurations
├───alice: NixOS configuration
├───bob: NixOS configuration
└───chloe: NixOS configuration
You can then build a single one of these configurations with nixos-rebuild build --flake .#alice
.
To find ways of reading and extracting data from json/yaml files, I recommend searching through the library and builtin functions on noogle. Nix currently has no builtin support for csv, and I don’t know of a library for that either.
To actually deploy this, you can build bootable images from these configurations with nixos-generators. You could then put an ISO on a stick to install the OS, or put an image on a PXE server and make a fully automated install. Not sure how sophisticated your operation is.
For maintenance, a good idea might also be to ensure that ssh is enabled by default, the hostname is set to something known like "${user}-pc"
and your public ssh key is already installed. Then, if you change something in the configuration.nix and want to deploy that, you can execute nixos-rebuild switch --flake .#alice --targetHost alice-pc
on your machine, it will rebuild the config, copy it to alice’s PC, ssh into it and execute nixos-rebuild switch
automatically.