diff --git a/morph/lib/base.nix b/morph/lib/base.nix
index 6fb5fccda4f19d4f39af543a8ca23b491205ab8d..b29cac0bbf53df075a8d8464fd08c4446e46bf37 100644
--- a/morph/lib/base.nix
+++ b/morph/lib/base.nix
@@ -18,6 +18,12 @@
       corresponding private keys for the system.
       '';
     };
+    monitoringEndpoint = lib.mkOption {
+      type = lib.types.str;
+      description = ''
+        The IPv4 address of the monitoring node this node should conenct to.
+      '';
+    };
     monitoringvpnIPv4 = lib.mkOption {
       type = lib.types.str;
       description = ''
@@ -57,14 +63,16 @@
     # qualified domain name.
     deployment.targetHost = config.networking.fqdn;
 
-    networking.hosts = {
-      # To stream logs to the monitoring host, all nodes need to know its address
-      ${nodes.monitoring.config.services.private-storage.monitoring.vpn.server.ip} = [
-        "monitoring" "monitoring.monitoringvpn"
-      ];
-    };
+    # This is the host that nodes should connect to for push-based monitoring.
+    # Note that this needs to be overridden on the monitoring host, otherwise
+    # we'd end up with infinite recursion.
+    grid.monitoringEndpoint = nodes.monitoring.config.grid.monitoringEndpoint;
 
-    services.private-storage.monitoring.exporters.promtail.enable = true;
+    # To stream logs to the monitoring host, all nodes need to know its address
+    services.private-storage.monitoring.exporters.promtail = {
+      enable = true;
+      serverHost = config.grid.monitoringEndpoint;
+    };
 
     assertions = [
       # This is a check to save somebody in the future trying to debug why
diff --git a/morph/lib/monitoring.nix b/morph/lib/monitoring.nix
index c955f09b109d7df5a705d221fe2bcc5b4e001aff..3ef624515eb52c3d447f1afdf5869507529c4b2c 100644
--- a/morph/lib/monitoring.nix
+++ b/morph/lib/monitoring.nix
@@ -92,6 +92,11 @@ in {
       }
     ];
 
+    # We use `mkForce` here, to override the value specified in `morph/lib/base.nix`,
+    # Since the default value depends on the value defined on this node, there
+    # would otherwise be infinite recursiion.
+    grid.monitoringEndpoint = lib.mkForce monitoringvpnIPv4;
+
     deployment.secrets = lib.mkMerge [
       {
         "monitoringvpn-private-key" = {
diff --git a/nixos/modules/monitoring/exporters/promtail.nix b/nixos/modules/monitoring/exporters/promtail.nix
index c056ebeb2c5982ae47c3df9707f30b5159b284d3..2a73d22ad123cc9017c975e85c35f9ce06c76785 100644
--- a/nixos/modules/monitoring/exporters/promtail.nix
+++ b/nixos/modules/monitoring/exporters/promtail.nix
@@ -15,6 +15,12 @@ let
 in {
   options.services.private-storage.monitoring.exporters.promtail = {
     enable = lib.mkEnableOption "Promtail log exporter service";
+    serverHost = lib.mkOption {
+      type = lib.types.str;
+      description = ''
+        The server host that logs should be pushed to.
+      '';
+    };
   };
 
   config = lib.mkIf cfg.enable {
@@ -28,7 +34,7 @@ in {
       };
 
       clients = [{
-          url = "http://monitoring:3100/loki/api/v1/push";
+          url = "http://${cfg.serverHost}:3100/loki/api/v1/push";
       }];
 
       scrape_configs = [{