{
  description = "CCCHH Nix Infrastructure";

  inputs = {
    # Use the NixOS small channels for nixpkgs.
    # https://nixos.org/manual/nixos/stable/#sec-upgrading
    # https://github.com/NixOS/nixpkgs
    nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11-small";

    # Add nixos-generators as an input.
    # See here: https://github.com/nix-community/nixos-generators#using-in-a-flake
    nixos-generators = {
      url = "github:nix-community/nixos-generators";
      #inputs.nixpkgs.follows = "nixpkgs";
    };

    # Add sops-nix as an input for secret management.
    # See here: https://github.com/Mic92/sops-nix?tab=readme-ov-file#flakes-current-recommendation
    sops-nix = {
      url = "github:Mic92/sops-nix";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    authorizedKeysRepo = {
      url = "https://git.hamburg.ccc.de/CCCHH/infrastructure-authorized-keys/archive/686a6af22f6696f0c0595c56f463c078550049fc.tar.gz";
      flake = false;
    };
  };

  outputs = { self, nixpkgs, nixos-generators, sops-nix, authorizedKeysRepo, ... }:
    let
      specialArgs = {
        inherit authorizedKeysRepo;
      };
      system = "x86_64-linux";
    in
    {
      nixosModules = {
        common = ./config/common;
        proxmox-vm = ./config/proxmox-vm;
        prometheus-exporter = ./config/extra/prometheus-exporter.nix;
      };
      nixosConfigurations = {
        audio-hauptraum-kueche = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            ./config/hosts/audio-hauptraum-kueche
          ];
        };

        audio-hauptraum-tafel = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            ./config/hosts/audio-hauptraum-tafel
          ];
        };

        esphome = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            ./config/hosts/esphome
          ];
        };

        public-reverse-proxy = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            ./config/hosts/public-reverse-proxy
          ];
        };

        matrix = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            sops-nix.nixosModules.sops
            self.nixosModules.prometheus-exporter
            ./config/hosts/matrix
          ];
        };

        public-web-static = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            sops-nix.nixosModules.sops
            self.nixosModules.prometheus-exporter
            ./config/hosts/public-web-static
          ];
        };

        git = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            sops-nix.nixosModules.sops
            self.nixosModules.prometheus-exporter
            ./config/hosts/git
          ];
        };

        forgejo-actions-runner = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            sops-nix.nixosModules.sops
            self.nixosModules.prometheus-exporter
            ./config/hosts/forgejo-actions-runner
          ];
        };

        ptouch-print-server = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            ./config/hosts/ptouch-print-server
          ];
        };

        nix-box-june = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            self.nixosModules.prometheus-exporter
            ./config/hosts/nix-box-june
          ];
        };

        yate = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            sops-nix.nixosModules.sops
            ./config/hosts/yate
          ];
        };

        mqtt = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            ./config/hosts/mqtt
          ];
        };

        mjolnir = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            sops-nix.nixosModules.sops
            self.nixosModules.prometheus-exporter
            ./config/hosts/mjolnir
          ];
        };

        woodpecker = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            sops-nix.nixosModules.sops
            self.nixosModules.prometheus-exporter
            ./config/hosts/woodpecker
          ];
        };

        status = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            sops-nix.nixosModules.sops
            ./config/hosts/status
          ];
        };

        penpot = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            sops-nix.nixosModules.sops
            self.nixosModules.prometheus-exporter
            ./config/hosts/penpot
          ];
        };

        hydra = nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [
            self.nixosModules.common
            self.nixosModules.proxmox-vm
            self.nixosModules.prometheus-exporter
            ./config/hosts/hydra
          ];
        };
      };

      packages.x86_64-linux = {
        proxmox-nixos-template = nixos-generators.nixosGenerate {
          inherit specialArgs;
          system = "x86_64-linux";
          modules = [
            ./config/nixos-generators/proxmox.nix
            self.nixosModules.common
            self.nixosModules.proxmox-vm
          ];
          format = "proxmox";
        };

        proxmox-chaosknoten-nixos-template = nixos-generators.nixosGenerate {
          inherit specialArgs;
          system = "x86_64-linux";
          modules = [
            ./config/nixos-generators/proxmox-chaosknoten.nix
            ./config/proxmox-chaosknoten-additional-initial-config.nix
            self.nixosModules.common
            self.nixosModules.proxmox-vm
          ];
          format = "proxmox";
        };
      };

      formatter.x86_64-linux = nixpkgs.legacyPackages.x86_64-linux.nixpkgs-fmt;

      hydraJobs = {
        inherit (self) packages;
        nixosConfigurations = builtins.mapAttrs (name: value: value.config.system.build.toplevel) self.nixosConfigurations;
      };
    };
}