ez-configs flake-parts module provides a flexible framework for managing configurations across multiple systems using nixosSystem, darwinSystem (nix-darwin), and homeManagerConfiguration (home-manager).
The module allows users to define system and user-specific configurations that are automatically when present. It is designed to work with a directory structure where configurations are organized by each configuration's hostname and username.
It's pretty opinionated, but aims to offer a degree of customizability.
Those two are created in quite analogous ways. Assuming most options are kept default and ezConfigs.root
is set to ./.
, host defined in ezConfigs.nixos.hosts
/ ezConfigs.darwin.hosts
get created using the following modules:
./nixos(.nix)
or./dariwn(.nix)
respectively, if present in your root./hosts/${hostname}(.nix)
if present in your root
This lets you define both platform specific and host specific configuration by simply adding nix files or directories to appropriate locations.
You're also able to define specialArgs
that will be passed to the appropriate system builders. A useful example would be passing in { inherit inputs; }
.
That way you can access your flake inputs from inside your nixos/darwin modules. They can either be set individually for each builder using ezConfigs.darwin.specialArgs
/ ezConfigs.nixos.specialArgs
or globally for all configuration builders with ezConfigs.globalArgs
.
It gets created using each user and system pair, with a name ${username}@${hostname}
. Users are defined in ezConfigs.hs.users
, while hosts are all the nixos and darwin configuration.
With the same assumptions as in the above section, the home manager configuration gets created using the package set of generated by the host system and using the following modules:
./home(.nix)
if present in your root./home/darwin(.nix)
or./home/linux(.nix)
respectively, if present in your root./users/${username}(.nix)
if present in your root./users/${username}/darwin(.nix)
or./users/${username}/linux(.nix)
respectively, if present in your root
This lets you define user and platform specific configurations in the same manner as with nixos and darwin configurations. You can also pass in extraSpecialArgs
which are the equivalent of specialArgs
of system builders.
Some of these are features that I'd like to look into, with no guarantee they get implemented since I'm not sure about how ergonomic to use they would be.
- Automatically discover hosts and users when a file is created the appropriate directory
- Allow for loading home manager as a nixos module when specified in user config, rather than creating a
homeManagerConfigurations
output - More configurability, like architecture dependent imports, changing the default
${username}@${hostname}
home manager configuration names, etc. - Extracting individual modules to flake outputs, so that then can be consumed by other flakes.
I use this module in my own dotfiles, but here's a basic flake.nix
structure you can use:
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05";
nixpkgs-darwin.url = "github:NixOS/nixpkgs/nixpkgs-23.05-darwin";
darwin = {
url = "github:lnl7/nix-darwin/master";
inputs.nixpkgs.follows = "nixpkgs-darwin";
};
home-manager = {
url = "github:nix-community/home-manager/release-23.05";
inputs.nixpkgs.follows = "nixpkgs";
};
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
ez-configs = {
url = "github:ehllie/ez-configs";
# We want to override the inputs of ez-configs
# That way you're able to update your system packages when running `nix flake update`
inputs = {
nixpkgs.follows = "nixpkgs";
nixpkgs-darwin.follows = "nixpkgs-darwin";
flake-parts.follows = "flake-parts";
darwin.follows = "darwin";
home-manager.follows = "home-manager";
};
};
};
outputs = inputs@{ flake-parts, ez-configs, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
imports = [
ez-configs.flakeModule
];
# mkFlake expects this to be present,
# so even if we don't use anything from perSystem, we need to set it to something.
# You can set it to anything you want if you also want to provide perSystem outputs in your flake.
systems = [ ];
ezConfigs = {
root = ./.;
globalArgs = { inherit inputs; };
hm.users = [
# {
# name = "your-username";
# }
];
darwin.hosts = [
# {
# name = "your-macbook-name";
# arch = "aarch64";
# }
];
nixos.hosts = [
# {
# name = "your-nixos-name";
# arch = "x86_64";
# }
];
};
};
}
If you were previously using something like configuration.nix
for your nixos configuratin, and home.nix
for your home manager configuration,
you can simply place the contents of the former inside ./hosts/your-nixos-name.nix
, and contents of the former in ./users/your-username.nix
.
Your nix-darwin configuration would go into ./hosts/your-macbook-name.nix
.
If you want to reuse some of your configuration across multiple machines or users, you can extract it into ./nixos.nix
/ ./nixos/defualt.nix
,
./darwin.nix
/ ./darwin/default.nix
or ./home.nix
/ ./home/default.nix
.