diff --git a/morph/lib/hardware-vagrant.nix b/morph/lib/hardware-vagrant.nix
index 4c118f2d3b735e5a0f5a6a0d84852fa8b99a1177..3fa375c640624a9422056d8dbd0242d69a196110 100644
--- a/morph/lib/hardware-vagrant.nix
+++ b/morph/lib/hardware-vagrant.nix
@@ -37,12 +37,15 @@
     # (maybe it could?  but why bother?) we do a bind-mount here so there is a
     # configured value readable.  The database won't really have a dedicated
     # volume but it will sort of appear as if it does.
-    fileSystems."voucher-database" = {
+    services.private-storage-issuer.voucherFileSystem = {
       device = "/var/lib/origin-zkapissuer-vouchers";
-      mountPoint = "/var/lib/zkapissuer-vouchers";
       options = ["bind"];
     };
+
+    # XXX This should be handled by the storage module like voucher-database
+    # is handled by the issuer module.
     fileSystems."/storage" = { fsType = "tmpfs"; };
+
     fileSystems."/" =
       { device = "/dev/sda1";
         fsType = "ext4";
diff --git a/morph/lib/issuer-aws.nix b/morph/lib/issuer-aws.nix
index ea90bb5fb23091a390eb1bb32c83a019cff3edd0..7c8f22a1c0887be4efe95399196b4623a1507393 100644
--- a/morph/lib/issuer-aws.nix
+++ b/morph/lib/issuer-aws.nix
@@ -18,15 +18,12 @@
   # <https://github.com/DBCDK/morph/issues/146>.
   networking.hostName = name;
 
-  fileSystems = {
-    # Mount a dedicated filesystem (ideally on a dedicated volume, but that's
-    # beyond control of this particular part of the system) for the
-    # PaymentServer voucher database.  This makes it easier to manage for
-    # tasks like backup/recovery and encryption.
-    "voucher-database" = {
-      label = "voucher-database";
-      mountPoint = "/var/lib/zkapissuer-vouchers";
-    };
+  # Mount a dedicated filesystem (ideally on a dedicated volume, but that's
+  # beyond control of this particular part of the system) for the
+  # PaymentServer voucher database.  This makes it easier to manage for
+  # tasks like backup/recovery and encryption.
+  services.private-storage-issuer.voucherFileSystem = {
+    label = "voucher-database";
   };
 
   # Clean up packages after a while
diff --git a/nixos/modules/issuer.nix b/nixos/modules/issuer.nix
index 58c658b1bc7a75635ea6bba11037342290f34afd..c5259690b0c047fa7ccc325883edec11e2009680 100644
--- a/nixos/modules/issuer.nix
+++ b/nixos/modules/issuer.nix
@@ -81,6 +81,15 @@ in {
         The kind of voucher database to use.
       '';
     };
+    services.private-storage-issuer.voucherFileSystem = lib.mkOption {
+      # Logically, the type is the type of an entry in fileSystems - but we'll
+      # just let the type system enforce that when we pass the value on to
+      # fileSystems.
+      description = ''
+        Configuration for a filesystem to mount which will hold the voucher
+        database.
+      '';
+    };
     services.private-storage-issuer.databasePath = lib.mkOption {
       default = null;
       type = lib.types.str;
@@ -115,6 +124,17 @@ in {
       internalHttpPort = "1061";
 
     in lib.mkIf cfg.enable {
+    # Make sure the voucher database filesystem is mounted.
+    fileSystems = {
+      "voucher-database" = cfg.voucherFileSystem // {
+        # Note that this path coincides with the StateDirectory we configure
+        # the systemd service with and the database path we configure
+        # PaymentServer with.  It is probably possible to have less repetition
+        # and more value sharing here.
+        mountPoint = "/var/lib/zkapissuer-vouchers";
+      };
+    };
+
     # Add a systemd service to run PaymentServer.
     systemd.services.zkapissuer = {
       enable = true;