How do I split common system configuration into seperate files

So, I have a repo with the configuration of a few separate machines. I’m using flakes and homemanager to setup most my configuration between them but there are a few things I want to keep the same that need to be put in my configuration.nix. I’ve tried factoring them out into a common nix module then importing it in imports. When I do that though I keep getting errors like has an unsupported attribute [whatever]. This is caused by introducing a top-level 'config' or 'options' attribute. Add configuration attributes immediately on the top level instead, or move all of them

I’m not sure how to get around that. What is the correct way to do this or is it just not possible?

without code i can’t be sure but it really shouldn’t be hard just declare the config as normal and import it

on my system i have split it into multiple files in ones i have

{home-manager-module,sops-module,nixpkgs, flake-registry}:{
   system = "x86_64-linux";
   modules = [
     home-manager-module
     sops-module
     (import ./neo-under-minus {inherit nixpkgs flake-registry;})
     {nixpkgs.overlays = [];}
   ];
}

and my default.nix in neo-under-minus is big but importantly i have

 imports = [./auto-gen-hardware.nix ./boot.nix ./admin.nix ./daily.nix ./guest.nix];

In my configuration.nix

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

{
  nix = {
    extraOptions = ''
      experimental-features = nix-command flakes
      min-free = ${toString (100 * 1024 * 1024)}
      max-free = ${toString (1024 * 1024 * 1024)}
    '';
  };
  imports =
    [
      # Include the results of the hardware scan.
      ./hardware-configuration.nix
      ../../common
    ];
# ...

My ./common/default.nix

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

  ##### Programs #####
  virtualisation = {
    podman = {
      enable = true; 
      # dockerCompat = true; # can conflict with docker
      defaultNetwork.settings = {
        dns_enable = true;
      };
    };
  };

  config.services.postgresql = {
    enable = true;
    ensureDatabases = [ "scratchdb" ];
    authentication = pkgs.lib.mkOverride 10 ''
      #type database  DBuser  auth-method
      local all       all     trust
    '';
  };

  ##### End Programs #####
  users.users.redacted = {
    isNormalUser = true;
    description = "redacted";
    extraGroups = [ "redacted" ];
    shell = pkgs.fish;
    packages = with pkgs; [
      firefox
    #  thunderbird
    ];
  };

  programs.fish.enable = true;
  # Allow unfree packages
  nixpkgs.config.allowUnfree = true;

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
  #  vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
    wget
    git
  ];

  # Enable auto optimiztion for the store
  nix.settings.auto-optimise-store = true;

  # Docker install with rootless
  virtualisation.docker.enable = true;
  virtualisation.docker.rootless = {
    enable = true;
    setSocketVariable = true;
  };

  # Garbage collection can be automated 
  nix.gc = {
    automatic = true;
    dates = "weekly";
    options = "--delete-older-than 30d";
  };

  environment.interactiveShellInit = ''
      	alias v='nvim'
      	alias vi='nvim'
    	alias vim='nvim'
    	alias ls='eza'
    	alias tree='eza -T'
    	alias gst='git status'
	alias lg='lazygit'
  '';
}

The error

error: Module `/nix/store/k31ay31mxnfj0nwy7dmwg61zs1qd7i8v-source/common' has an unsupported attribute `environment'. This is caused by introducing a top-level `config' or `options' attribute. Add configuration attributes immediately on the top level instead, or move all of them (namely: environment nix nixpkgs programs users virtualisation) into the explicit `config' attribute.

This error will pop up for any of the attributes I have set in common. I’m sure I’m just misunderstanding something.

why do you have config.services.postgresql instead of services.postgresql? i am fairly certain you only declare under config if you also are declaring options, like options = {something}; config = {otherthing};

I was just going by what they had in the documentation here for postgres. Even if I remove that, anything I have defined in the file will cause the same error.

config. and options. in front of the attribute of any option anywhere within your file causes that error.

The first bit of this chapter of the NixOS manual explains it: NixOS 23.11 manual | Nix & NixOS

The NixOS wiki has footguns like that here and there. It’s not a great resource most of the time, except a handful of pages. Technically you can make it work if you preface all options with config., the author of that page probably did so, likely also unaware of how NixOS modules work.

1 Like

Ahhh, that seemed to fix it. Thanks for the heads up!