Add grafana

Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
2025-04-07 21:51:34 +01:00
parent b3dd72de22
commit dc5a91ebf7
14 changed files with 533 additions and 9 deletions

View File

@@ -0,0 +1,239 @@
{
user ? throw "user argument is required",
home ? throw "home argument is required",
}:
{
config,
inputs,
pkgs,
system,
lib,
...
}:
let
selfPkgs = inputs.self.packages.${system};
hmConfig = config.home-manager.users.${user};
inherit (hmConfig.virtualisation.quadlet) volumes containers networks;
autheliaClientId = "4R5ofTZgOjO5Nrbcm9f6KqBLZXy8LwPS5s3E3BUfPS2mRy0wSV41XZGLrLgiR4Z0MblyGzW211AHL7GCCaJu5KonLUKyRjoyuiAr";
in
{
home-manager.users.${user} = {
sops = {
secrets = {
"grafana/authelia/password".sopsFile = ../../../../../../secrets/secrets.yaml;
"grafana/authelia/digest".sopsFile = ../../../../../../secrets/secrets.yaml;
"grafana/smtp".sopsFile = ../../../../../../secrets/secrets.yaml;
};
templates = {
"authelia-grafana.yaml".content = builtins.readFile (
(pkgs.formats.yaml { }).generate "grafana.yaml" {
identity_providers.oidc.clients = [
{
client_id = autheliaClientId;
client_name = "Grafana";
client_secret = hmConfig.sops.placeholder."grafana/authelia/digest";
redirect_uris = [ "https://stats.karaolidis.com/login/generic_oauth" ];
authorization_policy = "admin";
require_pkce = true;
pkce_challenge_method = "S256";
}
];
}
);
"grafana.ini".content = builtins.readFile (
(pkgs.formats.ini { }).generate "grafana.ini" {
server.root_url = "https://stats.karaolidis.com";
analytics = {
reporting_enabled = false;
check_for_updates = false;
check_for_plugin_updates = false;
};
security.disable_initial_admin_creation = true;
dashboards = {
versions_to_keep = 100;
min_refresh_interval = "1s";
};
users.default_theme = "system";
auth.disable_login_form = true;
sso_settings.configurable_providers = lib.strings.concatStringsSep " " [ ];
"auth.generic_oauth" = {
name = "Authelia";
icon = "signin";
enabled = true;
auto_login = true;
client_id = autheliaClientId;
client_secret = hmConfig.sops.placeholder."grafana/authelia/password";
auth_url = "https://id.karaolidis.com/api/oidc/authorization";
token_url = "https://id.karaolidis.com/api/oidc/token";
api_url = "https://id.karaolidis.com/api/oidc/userinfo";
use_pkce = true;
scopes = lib.strings.concatStringsSep " " [
"openid"
"profile"
"email"
"groups"
];
login_attribute_path = "preferred_username";
name_attribute_path = "name";
groups_attribute_path = "groups";
allow_assign_grafana_admin = true;
role_attribute_strict = true;
role_attribute_path = "contains(groups, 'admins') && 'GrafanaAdmin' || 'Viewer'";
org_attribute_path = "groups";
org_mapping = "admins:1:Admin *:1:Viewer";
};
smtp = {
enabled = true;
host = "smtp.protonmail.ch:587";
user = "jupiter@karaolidis.com";
password = hmConfig.sops.placeholder."grafana/smtp";
from_address = "jupiter@karaolidis.com";
};
unified_alerting.enabled = true;
"unified_alerting.screenshots".capture = true;
news.news_feed_enabled = false;
rendering = {
server_url = "http://grafana-image-renderer:8081/render";
callback_url = "http://grafana:3000";
};
plugins = {
plugin_admin_enabled = false;
preinstall = lib.strings.concatStringsSep " " [ ];
preinstall_async = false;
};
}
);
};
};
virtualisation.quadlet = {
networks = {
grafana.networkConfig.internal = true;
# Allow access to host telegraf via non-internal network
grafana-prometheus = { };
};
volumes = {
"grafana-prometheus-data" = { };
"grafana-prometheus-config" = { };
};
containers = {
"grafana-prometheus-init" =
let
prometheusConfig = (pkgs.formats.yaml { }).generate "prometheus.yml" {
global = {
scrape_interval = "10s";
evaluation_interval = "10s";
};
scrape_configs = [
{
job_name = "telegraf";
static_configs = [
{
targets = [ "host.containers.internal:9273" ];
labels.app = "telegraf";
}
{
targets = [
"host.containers.internal:${builtins.toString (9273 + config.users.users.${user}.uid)}"
];
labels.app = "telegraf-storm";
}
];
}
];
};
in
{
containerConfig = {
image = "docker-archive:${selfPkgs.docker-yq}";
volumes = [
"${volumes."grafana-prometheus-config".ref}:/etc/prometheus"
"${prometheusConfig}:/etc/prometheus/conf.d/prometheus.yml"
];
entrypoint = "/bin/bash";
exec = [
"-c"
"yq eval-all '. as $item ireduce ({}; . * $item)' /etc/prometheus/conf.d/*.yml > /etc/prometheus/prometheus.yml"
];
};
serviceConfig = {
Type = "oneshot";
Restart = "on-failure";
};
};
"grafana-prometheus" = {
containerConfig = {
image = "docker-archive:${selfPkgs.docker-prometheus}";
volumes = [
"${volumes."grafana-prometheus-config".ref}:/etc/prometheus"
"${volumes."grafana-prometheus-data".ref}:/var/lib/prometheus"
];
networks = [
networks.grafana.ref
networks.grafana-prometheus.ref
];
exec = [
"--config.file=/etc/prometheus/prometheus.yml"
"--storage.tsdb.path=/var/lib/prometheus"
"--storage.tsdb.retention.time=1y"
"--log.level=warn"
];
};
unitConfig.After = [ "${containers."grafana-prometheus-init"._serviceName}.service" ];
};
grafana = {
containerConfig = {
image = "docker-archive:${selfPkgs.docker-grafana}";
networks = [
networks.grafana.ref
networks.traefik.ref
];
volumes = [ "${hmConfig.sops.templates."grafana.ini".path}:/etc/grafana/grafana.ini" ];
labels = [
"traefik.enable=true"
"traefik.http.routers.grafana.rule=Host(`stats.karaolidis.com`)"
];
};
unitConfig.After = [
"${containers."grafana-prometheus"._serviceName}.service"
"${containers."grafana-image-renderer"._serviceName}.service"
];
};
"grafana-image-renderer" = {
containerConfig = {
image = "docker-archive:${selfPkgs.docker-grafana-image-renderer}";
networks = [ networks.grafana.ref ];
};
};
authelia.containerConfig.volumes = [
"${hmConfig.sops.templates."authelia-grafana.yaml".path}:/etc/authelia/conf.d/grafana.yaml:ro"
];
};
};
};
}