nix/modules/monitoring/grafana.nix
2025-12-04 08:48:18 +01:00

174 lines
4.5 KiB
Nix

{
config,
pkgs,
lib,
...
}:
with lib;
let
cfg = config.my.monitoring.grafana;
in
{
options.my.monitoring.grafana = {
enable = lib.mkEnableOption "Enable grafana as a data visualization";
adminPasswordFile = lib.mkOption {
default = "";
type = lib.types.str;
description = ''
Path to the file containing the admin password for Grafana
'';
};
auth = {
enable = lib.mkEnableOption "Enable authentication (Authentik) for Grafana";
baseUrl = lib.mkOption {
default = "https://auth.example.com";
type = lib.types.str;
description = ''
The base URL of the Authentik instance
'';
};
sectetKeyFile = lib.mkOption {
default = "";
type = lib.types.path;
description = ''
Path to the file containing the secret key for Grafana
'';
};
};
proxy = {
enable = lib.mkEnableOption "Set the proxy entry for this service";
domain = lib.mkOption {
default = "example.com";
type = lib.types.str;
description = ''
The domain where Caddy is reachable
'';
};
subdomain = lib.mkOption {
default = "grafana";
type = lib.types.str;
description = ''
The subdomain where Grafana is reachable
'';
};
host = lib.mkOption {
default = "localhost";
type = lib.types.str;
description = ''
Host name where Grafana is running
'';
};
};
};
config = lib.mkMerge [
(lib.mkIf cfg.enable {
services = {
grafana = {
enable = true;
settings = {
analytics.reporting_enabled = false;
auth = lib.mkIf cfg.auth.enable {
signout_redirect_url = "https://${cfg.auth.baseUrl}/application/o/grafana/end-session/";
disable_login_form = true;
};
"auth.generic_oauth" = {
name = "authentik";
enabled = cfg.auth.enable;
client_id = "GpPQl4K55kQQhIeuIgzN27kzPzSpY5HlpmqpU9sy";
client_secret = "$__file{${cfg.auth.sectetKeyFile}}";
scopes = "openid email profile";
auth_url = "https://${cfg.auth.baseUrl}/application/o/authorize/";
token_url = "https://${cfg.auth.baseUrl}/application/o/token/";
api_url = "https://${cfg.auth.baseUrl}/application/o/userinfo/";
# Optionally map user groups to Grafana roles";
role_attribute_path = "contains(groups, 'Grafana Admins') && 'Admin' || contains(groups, 'Grafana Editors') && 'Editor' || 'Viewer'";
};
database = {
user = "grafana";
type = "postgres";
host = "/run/postgresql/";
name = "grafana";
};
security = {
admin_user = "pazpi";
admin_password = "$__file{${cfg.adminPasswordFile}}";
};
server = {
domain = cfg.proxy.domain;
http_addr = "0.0.0.0";
http_port = 3000;
root_url = "https://${cfg.proxy.subdomain}.${cfg.proxy.domain}";
enable_gzip = true;
};
users = {
default_theme = "light";
allow_sign_up = false;
};
};
# XXX Just for future reference
# provision.dashboards.settings.providers = [
# {
# name = "example";
# options.path = ./dashboards/example.json;
# }
# ];
};
grafana-image-renderer = {
enable = true;
settings.browser.path = lib.getExe pkgs.ungoogled-chromium;
provisionGrafana = true;
};
postgresql = {
enable = true;
ensureDatabases = [ "grafana" ];
ensureUsers = [
{
name = "grafana";
ensureDBOwnership = true;
}
];
};
};
networking.firewall.allowedTCPPorts = [ 3000 ];
})
(lib.mkIf cfg.proxy.enable {
services.caddy = with cfg.proxy; {
virtualHosts."${subdomain}.${domain}".extraConfig = ''
reverse_proxy http://${host}:3000
import cloudflare_${domain}
'';
};
})
];
}
# {
# name = "Alertmanager";
# type = "alertmanager";
# url = "http://nuc:9093";
# jsonData.implementation = "prometheus";
# jsonData.handleGrafanaManagedAlerts = true;
# }