diff --git a/README.md b/README.md
index bbfe36a..e4369b4 100644
--- a/README.md
+++ b/README.md
@@ -21,10 +21,13 @@ admin list below) or create an issue here:
 
 ## Services
 
-* https://hydra.nix-community.org - on build01
 * BuildKite agent - on build01
 * GitLab agent - on build01
-* ryantm-updater bot - on build01
+* hound - on build01
+* https://hydra.nix-community.org - on build01
+* marvin-mk2 - on build01
+* matterbridge - on build01
+* ryantm-updater bot - on build02
 
 ## Hosts
 
@@ -46,14 +49,30 @@ This machine currently just runs r-ryantm/nixpkgs-update.
 * RAM: 64GB DDR4 ECC
 * Drives: 2 x 1 TB NVME in RAID 1
 
+### `build03`
+
+This machine is a replacement for build01.
+
+* Provider: Hetzner
+* CPU: AMD Ryzen 5 3600 6-Core Processor
+* RAM: 64GB DDR4 ECC
+* Drives: 2 x 512 TB NVME in RAID 1
+
 ## Cache
 
 All the builds on these machines are pushed to https://nix-community.cachix.org/
 
 Thanks to Cachix for sponsoring our binary cache!
 
-## Usage
+## File hierarchy
 
-* `./deploy` - NixOps deployment
+* ./build\d+ - build machines
+* ./ci.sh - What is executed by CI
+* ./deploy - NixOps deploy script
+* ./nix - pinned Nix dependencies and overlays
+* ./roles - shared NixOS configuration modules
+* ./secrets - git-crypt encrypted secrets
+* ./services - single instances of NixOS services
 * ./terraform - Setup DNS
+* ./users - NixOS configuration of our admins
 
diff --git a/build01/configuration.nix b/build01/configuration.nix
index 9891832..7a3b9c5 100644
--- a/build01/configuration.nix
+++ b/build01/configuration.nix
@@ -3,18 +3,16 @@
   imports = [
     ./hardware-configuration.nix
 
-    ./buildkite.nix
-    ./gitlab.nix
-    ./hydra.nix
-    ./hydra-declarative-projects.nix
-    ./cache.nix
-    ./marvin-mk2.nix
-    ./matterbridge.nix
-
-    ../profiles/common.nix
-    ../services/docker.nix
+    ../roles/buildkite.nix
+    ../roles/common.nix
+    ../roles/docker.nix
+    ../roles/gitlab-runner.nix
+    ../roles/nginx.nix
+    ../roles/nix-community-cache.nix
     ../services/hound
-    ../services/nginx.nix
+    ../services/hydra
+    ../services/marvin-mk2.nix
+    ../services/matterbridge.nix
   ];
 
   # /boot is a mirror raid
diff --git a/build02/cache.nix b/build02/cache.nix
deleted file mode 100644
index a82a177..0000000
--- a/build02/cache.nix
+++ /dev/null
@@ -1,48 +0,0 @@
-{ config, pkgs, ... }:
-let
-  postBuildHook = pkgs.writeScript "post-build-hook.sh" ''
-    #!${pkgs.runtimeShell}
-    export PATH=$PATH:${pkgs.nix}/bin
-    exec ${pkgs.cachix}/bin/cachix -c /var/lib/post-build-hook/nix-community-cachix.dhall push nix-community $OUT_PATHS
-  '';
-
-  sockPath = "/run/post-build-hook.sock";
-
-  queueBuildHook = pkgs.writeScript "post-build-hook.sh" ''
-    ${pkgs.queued-build-hook}/bin/queued-build-hook queue --socket ${sockPath}
-  '';
-
-  sources = import ../nix/sources.nix;
-
-in
-{
-
-  nixpkgs.overlays = [
-    (self: super: {
-      queued-build-hook = (import sources.queued-build-hook { pkgs = super; });
-    })
-  ];
-
-  systemd.sockets.queued-build-hook = {
-    description = "Post-build-hook socket";
-    wantedBy = [ "sockets.target" ];
-    socketConfig = {
-      ListenStream = sockPath;
-      SocketUser = "root";
-      SocketMode = "0600";
-    };
-  };
-
-  systemd.services.queued-build-hook = {
-    description = "Post-build-hook service";
-    wantedBy = [ "multi-user.target" ];
-    after = [ "network.target" "queued-build-hook.socket" ];
-    requires = [ "queued-build-hook.socket" ];
-    serviceConfig.ExecStart = "${pkgs.queued-build-hook}/bin/queued-build-hook daemon --retry-interval 30 --hook ${postBuildHook}";
-  };
-
-  nix.extraOptions = ''
-    post-build-hook = ${queueBuildHook}
-  '';
-
-}
diff --git a/build02/configuration.nix b/build02/configuration.nix
index 0d8d6b2..1c3cbbd 100644
--- a/build02/configuration.nix
+++ b/build02/configuration.nix
@@ -4,11 +4,11 @@
   imports = [
     ./hardware-configuration.nix
 
-    ./cache.nix
     ./nixpkgs-update.nix
 
-    ../profiles/common.nix
-    ../services/nginx.nix
+    ../roles/common.nix
+    ../roles/nginx.nix
+    ../roles/nix-community-cache.nix
   ];
 
   # /boot is a mirror raid
diff --git a/build03/configuration.nix b/build03/configuration.nix
index ea8fbf2..53cb7a7 100644
--- a/build03/configuration.nix
+++ b/build03/configuration.nix
@@ -10,8 +10,8 @@
   imports = [
     ./hardware-configuration.nix
 
-    ../profiles/common.nix
-    ../profiles/hetzner-network.nix
+    ../roles/common.nix
+    ../roles/hetzner-network.nix
   ];
 
   # /boot is a mirror raid
diff --git a/default.nix b/default.nix
index f37b2fe..1acd3eb 100644
--- a/default.nix
+++ b/default.nix
@@ -13,4 +13,6 @@ pkgs.nix-community-infra // rec {
   build01-system = build01.system;
   build02 = importNixOS ./build02/configuration.nix "x86_64-linux";
   build02-system = build02.system;
+  build03 = importNixOS ./build02/configuration.nix "x86_64-linux";
+  build03-system = build03.system;
 }
diff --git a/build01/buildkite.nix b/roles/buildkite.nix
similarity index 100%
rename from build01/buildkite.nix
rename to roles/buildkite.nix
diff --git a/profiles/common.nix b/roles/common.nix
similarity index 92%
rename from profiles/common.nix
rename to roles/common.nix
index a271723..2e04a95 100644
--- a/profiles/common.nix
+++ b/roles/common.nix
@@ -3,12 +3,12 @@
 {
 
   imports = [
+    ./nix-daemon.nix
     ./security.nix
-    ../services/nix-daemon.nix
-    ../services/sshd.nix
-    ../services/telegraf
-    ./zfs.nix
+    ./sshd.nix
+    ./telegraf
     ./users.nix
+    ./zfs.nix
   ];
 
   environment.systemPackages = [
diff --git a/services/docker.nix b/roles/docker.nix
similarity index 100%
rename from services/docker.nix
rename to roles/docker.nix
diff --git a/build01/gitlab.nix b/roles/gitlab-runner.nix
similarity index 100%
rename from build01/gitlab.nix
rename to roles/gitlab-runner.nix
diff --git a/profiles/hetzner-network.nix b/roles/hetzner-network.nix
similarity index 100%
rename from profiles/hetzner-network.nix
rename to roles/hetzner-network.nix
diff --git a/profiles/kexec.nix b/roles/kexec.nix
similarity index 97%
rename from profiles/kexec.nix
rename to roles/kexec.nix
index 38984b2..d013f8d 100644
--- a/profiles/kexec.nix
+++ b/roles/kexec.nix
@@ -4,7 +4,7 @@
 {
   imports = [
     ./users.nix
-    ../sshd.nix
+    ./sshd.nix
   ];
 }
 
diff --git a/services/nginx.nix b/roles/nginx.nix
similarity index 100%
rename from services/nginx.nix
rename to roles/nginx.nix
diff --git a/build01/cache.nix b/roles/nix-community-cache.nix
similarity index 100%
rename from build01/cache.nix
rename to roles/nix-community-cache.nix
diff --git a/services/nix-daemon.nix b/roles/nix-daemon.nix
similarity index 100%
rename from services/nix-daemon.nix
rename to roles/nix-daemon.nix
diff --git a/profiles/security.nix b/roles/security.nix
similarity index 100%
rename from profiles/security.nix
rename to roles/security.nix
diff --git a/services/sshd.nix b/roles/sshd.nix
similarity index 100%
rename from services/sshd.nix
rename to roles/sshd.nix
diff --git a/services/telegraf/default.nix b/roles/telegraf/default.nix
similarity index 100%
rename from services/telegraf/default.nix
rename to roles/telegraf/default.nix
diff --git a/services/telegraf/mdraid-health.sh b/roles/telegraf/mdraid-health.sh
similarity index 100%
rename from services/telegraf/mdraid-health.sh
rename to roles/telegraf/mdraid-health.sh
diff --git a/profiles/users.nix b/roles/users.nix
similarity index 100%
rename from profiles/users.nix
rename to roles/users.nix
diff --git a/profiles/zfs.nix b/roles/zfs.nix
similarity index 100%
rename from profiles/zfs.nix
rename to roles/zfs.nix
diff --git a/build01/create-declarative-project.sh b/services/hydra/create-declarative-project.sh
similarity index 100%
rename from build01/create-declarative-project.sh
rename to services/hydra/create-declarative-project.sh
diff --git a/build01/hydra-declarative-projects.nix b/services/hydra/declarative-projects.nix
similarity index 100%
rename from build01/hydra-declarative-projects.nix
rename to services/hydra/declarative-projects.nix
diff --git a/build01/hydra.nix b/services/hydra/default.nix
similarity index 99%
rename from build01/hydra.nix
rename to services/hydra/default.nix
index 613737d..b6560ad 100644
--- a/build01/hydra.nix
+++ b/services/hydra/default.nix
@@ -22,6 +22,8 @@ let
 
 in
 {
+  imports = [ ./declarative-projects.nix ];
+
   options.services.hydra = {
     adminPasswordFile = mkOption {
       type = types.str;
diff --git a/build01/marvin-mk2.nix b/services/marvin-mk2.nix
similarity index 100%
rename from build01/marvin-mk2.nix
rename to services/marvin-mk2.nix
diff --git a/build01/matterbridge.nix b/services/matterbridge.nix
similarity index 84%
rename from build01/matterbridge.nix
rename to services/matterbridge.nix
index 1c9ebd7..a01b478 100644
--- a/build01/matterbridge.nix
+++ b/services/matterbridge.nix
@@ -1,3 +1,4 @@
+# A single instance of matterbridge
 { ... }: {
   services.matterbridge.enable = true;
   services.matterbridge.configPath = "/run/keys/matterbridge.toml";