{
  description = "Fudo Host Configuration";

  inputs = {
    nixpkgs.url = "nixpkgs/nixos-21.05";

    fudo-home.url = "git+https://git.fudo.org/fudo-nix/home.git";

    # This MUST be a clean git repo, because we use the timestamp.
    fudo-entities = {
      url = "git+https://git.fudo.org/fudo-nix/entities.git";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    fudo-lib = {
      #url = "git+https://git.fudo.org/fudo-nix/lib.git";
      url = "path:/state/fudo-lib";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    fudo-pkgs.url = "git+https://git.fudo.org/fudo-nix/pkgs.git";

    fudo-secrets.url = "path:/state/secrets";

    chute.url = "git+https://git.fudo.org/chute/chute.git?ref=stable";

    chuteUnstable.url = "git+https://git.fudo.org/chute/chute.git?ref=master";
  };

  outputs = { self,
              nixpkgs,
              fudo-home,
              fudo-lib,
              fudo-entities,
              fudo-pkgs,
              fudo-secrets,
              chute,
              chuteUnstable,
              ... } @ inputs:
    with nixpkgs.lib;
    let
      fudo-nixos-hosts = filterAttrs
        (hostname: hostOpts: hostOpts.nixos-system)
        (fudo-entities.entities.hosts);

      fudo-networks = fudo-entities.entities.networks;

      pkgs-for = arch: import nixpkgs {
        system = arch;
        config = {
          allowUnfree = true;
          permittedInsecurePackages = [
            "openssh-with-gssapi-8.4p1"
          ];
        };
        overlays = [
          fudo-lib.overlay
          fudo-pkgs.overlay
          (final: prev: {
            chute = chute.packages.${arch}.chute;
            chuteUnstable = chuteUnstable.packages.${arch}.chute;
          })
        ];
      };

      latest-modified-timestamp = head
        (sort (a: b: a > b)
          (map (input: toInt input.lastModifiedDate)
            (filter (input: hasAttr "lastModifiedDate" input)
              (attrValues inputs))));

      concat-timestamp = timestamp:
        toInt (substring 0 10 (toString timestamp));

      common-host-config = hostname: hostOpts: let
        config-dir = ./config;
        build-timestamp =
          concat-timestamp latest-modified-timestamp;
      in { config, ... }: {
        imports = [
          fudo-home.nixosModule
          fudo-secrets.nixosModule
          fudo-lib.nixosModule
          fudo-entities.nixosModule

          ./config
          (config-dir + /hardware/${hostname}.nix)
          (config-dir + /host-config/${hostname}.nix)
          (config-dir + /profile-config/${hostOpts.profile}.nix)
          (config-dir + /domain-config/${hostOpts.domain}.nix)
          (config-dir + /site-config/${hostOpts.site}.nix)
        ];

        config = {
          instance = let
            build-seed = builtins.readFile
              config.fudo.secrets.files.build-seed;
          in {
            inherit hostname build-timestamp build-seed;
          };

          nix.registry = {
            fudo-nixos.flake = self;
            fudo-entities.flake = fudo-entities;
            fudo-lib.flake = fudo-lib;
            fudo-pkgs.flake = fudo-pkgs;
          };

          nixpkgs.pkgs = pkgs-for hostOpts.arch;
        };
      };

      nixos-host-config = hostname: hostOpts: let
        system = hostOpts.arch;
      in nixosSystem {
        inherit system;
        modules = [
          (common-host-config hostname hostOpts)
        ];
      };

      nixops-host-config = hostname: hostOpts: let
        zone-hosts = fudo-entities.entities.zones.${hostOpts.domain}.hosts;
      in {
        imports = [
          (common-host-config hostname hostOpts)

          ({ ... }: {
            config.deployment.targetHost =
              zone-hosts.${hostname}.ipv4-address;
          })
        ];
      };

    in {
      nixosConfigurations = mapAttrs nixos-host-config fudo-nixos-hosts;
      nixopsHostConfigurations = mapAttrs nixops-host-config fudo-nixos-hosts;
    };
}