Create custom module for system configuration

My setup currently uses a “system/<hostname>/configuration.nix” in a git repo to define host specific configuration like the hardware and the imports function to import other .nix files like “core.nix” for common configuration across multiple hosts.
I am starting to get to the point where I need slight differences in my user configurations and I would like to define options to reflect these differences but I cannot find an example that shows me how to do this that doesn’t also include other complexities above and beyond what I am trying to accomplish.

For example I have (users):


Each user has a specific uid, primary group, shell etc that doesn’t change, but I dont always want all users installed, and when I do I need to customize what users may have wheel access and all users need to be in the network manager group but only if network manager is enabled on that system.

So in my configuration.nix I would like to define something like:

mynamespace.user.adminuser.enable = true;   # Redundant, defaults to true for enable and isWheel
mynamespace.user.child2.enable = true;  # (defaults to false) Only installed on specific systems.
mynamespace.user.myuser { # Is installed on every system
  enable = true           # Redundant, (defaults to true)
  isWheel = true         # Add this user to the wheel group Redundant, (defaults to true)
mynamespace.user.child1 {
  enable = true           # enable the user with all the preconfigured defaults for that user. (defaults to false)
  isWheel = true         # Add this user to the wheel group (it is her pc)  (defaults to false)

And the users should automatically be added the the networkmanager group if it is in use on the system. I currently have my users each in their own <user>.nix file and am using imports to apply which user is placed on each system.

Below is a link I l read through but it has way more going on that what I need and I dont know enough to separate out the complexities. And most other resources on creating modules are about packaging/installing applications, not system configuration. – I wasnt sure how to remove all the homemanager additions and adapt it to my much simpler use case.

So, how do I create a module that lets me define those user options under my own namespace (to avoid conflicts) and apply them to a host configuration using my <user>.nix files as a base for the static options? Or is there a better way to do what I am trying to accomplish?

  1. enable predefined users in a custom options namespace with defaults in place
  2. Toggle wheel for each user with defaults in place
  3. Have the users automatically added to networkmanager group only if networkmanager is installed.

Any help or resources that are applicable to my use case would be greatly appreciated. Once I wrap my head around how to accomplish these 3 main things I should be able to adapt it to the rest of my configuration as needed.

You can define any custom options you want inside the options attr. See eg
Then all previous defined options must be moved to config.

Each of your “.nix” file is a nix module. Based on my understanding of your question, what you can do as a first step is:

  1. Add options to child1.nix controlling whether it is enabled and whether it is added to wheel etc
  2. Still import child1.nix in your configuration.nix.
  3. In configuration.nix, you can specify/override the mynamespace.user.child1.enable and mynamespace.user.child1.isWheel.

To achieve that, child1.nix should look like

{ config, lib, pkgs, ... }:

let cfg = config.mynamespace.user.child1;

in {
  options.mynamespace.user.child1 = with lib; {
    enable = lib.mkEnableOption "Enable the userchild1";
    isWheel = lib.mkOption {
      type = lib.types.bool;
      default = true;
      description = ''
        whether add to the group wheel                  

  config = lib.mkIf cfg.enable {
    users = {
      extraUsers = {
        "child1" = {
          uid = xxxx;
          extraGroups = [
            ... # other groups
          ] ++ lib.lists.optionals cfg.isWheel [ "wheel" ];;

Please note the usage of lib.mkIf and lib.lists.optionals.