{
  description = "Homelab configuration";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    impermanence.url = "github:nix-community/impermanence";

    # Sops-nix, a secrets manager
    sops-nix.url = "github:Mic92/sops-nix";
    sops-nix.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs =
    { self, nixpkgs, ... }@inputs:
    let
      lib = nixpkgs.lib;
      outputs = self.outputs;

      dockerImages = import ./dockerImages.nix;
      homelabConfig = import ./config.nix;
      utils = import ./utils.nix { inherit inputs homelabConfig; };

      roles = import ./roles.nix { inherit utils lib; };
      hosts = import ./hosts.nix {
        inherit
          homelabConfig
          roles
          utils
          lib
          ;
      };
      pkgs = nixpkgs.legacyPackages.x86_64-linux;
    in
    {
      devShells.x86_64-linux.default = pkgs.mkShell {
        buildInputs = with pkgs; [
          colmena
          sops
        ];
      };
      colmena =
        {
          meta = {
            nixpkgs = import nixpkgs {
              system = "x86_64-linux";
            };
            specialArgs = {
              inherit
                inputs
                outputs
                hosts
                dockerImages
                ;
            };
            nodeSpecialArgs = builtins.mapAttrs (_: cfg: { host = cfg; }) hosts;
          };
        }
        // (nixpkgs.lib.mapAttrs (
          _: value:
          (utils.mkSystem {
            hostConfig = value;
          })
        ) (lib.attrsets.filterAttrs (_: host: host.managed) hosts));
      nixosConfigurations = {
        template = nixpkgs.lib.nixosSystem {
          specialArgs = { inherit inputs; };
          modules = [ ./systems/template/configuration.nix ];
        };
      };
    };
}