Newer
Older
skyworks-Nix-infra / modules / influxdb.nix
# InfluxDB v2 time-series database for infrastructure monitoring.
#
# Data lives on ZFS (dick/system/influxdb) for compression, snapshots,
# and infinite retention. All Telegraf instances across the fleet write
# here; Grafana on door1 queries the HTTP API.
#
# ZFS dataset (create once, manually):
#   zfs create -o recordsize=128K -o mountpoint=/srv/system/influxdb \
#     -o quota=500G dick/system/influxdb
#   chown influxdb:influxdb /srv/system/influxdb
#
{ config, lib, pkgs, ... }:

let
  cfg = config.skyworks.influxdb;
in {
  options.skyworks.influxdb = {
    enable = lib.mkEnableOption "InfluxDB v2 on ZFS-backed storage";

    dataDir = lib.mkOption {
      type = lib.types.path;
      default = "/srv/system/influxdb";
      description = "InfluxDB data directory (should be a ZFS dataset)";
    };

    port = lib.mkOption {
      type = lib.types.port;
      default = 8086;
      description = "InfluxDB HTTP API listen port";
    };
  };

  config = lib.mkIf cfg.enable {
    services.influxdb2 = {
      enable = true;
      settings = {
        http-bind-address = ":${toString cfg.port}";
      };
    };

    # Bind-mount the ZFS dataset over the default StateDirectory so
    # NixOS's influxdb2 module manages bolt/engine/sqlite paths as
    # usual, but the actual data lands on ZFS.
    fileSystems."/var/lib/influxdb2" = {
      device = cfg.dataDir;
      fsType = "none";
      options = [ "bind" ];
    };

    # Ensure the ZFS mountpoint directory exists
    systemd.tmpfiles.rules = [
      "d ${cfg.dataDir} 0700 influxdb influxdb -"
    ];

    # Wait for ZFS to mount the dataset before starting InfluxDB
    systemd.services.influxdb2 = {
      after = [ "zfs-mount.service" ];
      wants = [ "zfs-mount.service" ];
    };

    # Open firewall for internal network only
    networking.firewall.allowedTCPPorts = [ cfg.port ];
  };
}