{
  description = "tlater.net host configuration";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-22.05";
    sops-nix = {
      url = "github:Mic92/sops-nix";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    tlaternet-webserver = {
      url = "git+https://gitea.tlater.net/tlaternet/tlaternet.git";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = {
    self,
    nixpkgs,
    sops-nix,
    tlaternet-webserver,
  }: let
    system = "x86_64-linux";
  in {
    ##################
    # Configurations #
    ##################
    nixosConfigurations = let
      # Modules that should be generic to all systems
      genericModule = {...}: {
        imports = [
          # Inject flake dependencies
          sops-nix.nixosModules.sops
          tlaternet-webserver.nixosModules.default

          # Import actual configuration
          (import ./configuration)
        ];
      };
    in {
      # The actual system definition
      tlaternet = nixpkgs.lib.nixosSystem {
        inherit system;
        modules = [
          genericModule
          (import ./configuration/hardware-specific/linode)
        ];
      };

      # A qemu VM to test the above with
      vm = nixpkgs.lib.nixosSystem {
        inherit system;
        modules = [
          genericModule
          (import ./configuration/hardware-specific/vm.nix)
        ];
      };
    };

    ####################
    # Helper functions #
    ####################
    lib = import ./lib {lib = nixpkgs.lib;};

    ####################
    # VM launch script #
    ####################
    apps.${system}.default = let
      inherit (self.nixosConfigurations.vm.config.system.build) vm;
      inherit (nixpkgs.legacyPackages.${system}) writeShellScript;
      qemuNetOpts = self.lib.makeQemuNetOpts {
        "2222" = "2222";
        "3080" = "80";
        "3443" = "443";
        "21025" = "21025"; # Starbound
      };
    in {
      type = "app";
      program = builtins.toString (writeShellScript "run-vm" ''
        export QEMU_OPTS="-m 3941 -smp 2 -curses"
        export QEMU_NET_OPTS="${qemuNetOpts}"
        "${vm}/bin/run-tlaternet-vm"
      '');
    };

    ###########################
    # Development environment #
    ###########################
    devShells.${system}.default = let
      inherit (sops-nix.packages.${system}) sops-import-keys-hook sops-init-gpg-key;
      deploy-rs-bin = deploy-rs.packages.${system}.default;
      pkgs = nixpkgs.legacyPackages.${system};
    in
      nixpkgs.legacyPackages.${system}.mkShell {
        sopsPGPKeyDirs = ["./keys/hosts/" "./keys/users/"];
        nativeBuildInputs = [
          sops-import-keys-hook
        ];
        packages = with pkgs; [
          nixfmt
          git-lfs
          sops-init-gpg-key
          deploy-rs-bin
        ];

        shellHook = ''
          # Work around sudo requiring a full terminal when deploying to
          # a remote host
          export NIX_SSHOPTS="-t"
        '';
      };
  };
}