# values/grafana.values.yaml # --- Admin credentials via Vault/ESO --- # Admin username & password are stored in Vault at: # secret/grafana-admin # and pulled into a K8s Secret grafana-admin-secret by ExternalSecret. # admin: # existingSecret: grafana-admin-secret # userKey: admin-user # passwordKey: admin-password # These plain values are ignored when existingSecret is set, but leave # them harmless defaults so you can still helm template without ESO. adminUser: admin adminPassword: "admin" # --- Recreate strategy to avoid RWO PVC Multi-Attach deadlock --- strategy: type: Recreate # --- Deployment annotations for Reloader --- # Automatically restart Grafana when secrets change # Note: Unpoller has its own Reloader annotation in unpoller namespace deploymentAnnotations: secret.reloader.stakater.com/reload: "grafana-authentik-oauth,grafana-teslamate-datasource" # --- Persistence for dashboards and config --- persistence: enabled: true type: pvc storageClassName: rook-ceph-block accessModes: - ReadWriteOnce size: 10Gi # --- Service type --- service: type: ClusterIP # Security context for Talos compatibility securityContext: runAsUser: 472 runAsGroup: 472 runAsNonRoot: true fsGroup: 472 # --- Ingress disabled - Istio VirtualService handles routing --- ingress: enabled: false # --- Authentik OIDC Integration --- # ============================================================================ # AUTOMATIC ADMIN ACCESS - BOOTSTRAP READY # ============================================================================ # Role mapping assigns Grafana roles based on Authentik group membership: # # Authentik Group → Grafana Role # ───────────────────────────────────────────────────────── # authentik Admins → Admin (full access) - AUTOMATIC! # Grafana Admins → Admin (full access) # Grafana Editors → Editor (can edit dashboards) # Grafana Viewers → Viewer (read-only) # (any other user) → Viewer (read-only) # # BOOTSTRAP BEHAVIOR: # ✓ authentik Admins get automatic Grafana admin access (no manual config!) # ✓ Groups auto-created by Authentik blueprint during bootstrap # ✓ Add users to groups in Authentik UI for access control # # TO GRANT ADMIN ACCESS TO OTHER USERS: # 1. Log into Authentik at https://auth.kube.huskypup.net # 2. Go to Directory → Groups → "Grafana Admins" # 3. Add users to the group # 4. Users log out/in to Grafana to receive admin role # ============================================================================ grafana.ini: server: root_url: https://grafana.kube.huskypup.net auth.generic_oauth: enabled: true name: Authentik scopes: openid profile email auth_url: https://auth.kube.huskypup.net/application/o/authorize/ token_url: https://auth.kube.huskypup.net/application/o/token/ api_url: https://auth.kube.huskypup.net/application/o/userinfo/ # Role mapping: authentik Admins OR Grafana Admins → Admin, Grafana Editors → Editor, else → Viewer role_attribute_path: contains(groups[*], 'authentik Admins') && 'Admin' || contains(groups[*], 'Grafana Admins') && 'Admin' || contains(groups[*], 'Grafana Editors') && 'Editor' || 'Viewer' allow_sign_up: true client_id: $__env{GF_AUTH_GENERIC_OAUTH_CLIENT_ID} client_secret: $__env{GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET} # Load OAuth credentials and datasource passwords from secrets as environment variables envFromSecrets: - name: grafana-authentik-oauth - name: grafana-teslamate-datasource # --- Datasources --- datasources: datasources.yaml: apiVersion: 1 datasources: - name: Prometheus type: prometheus uid: Prometheus url: http://kube-prometheus-stack-prometheus.prometheus.svc.cluster.local:9090 access: proxy isDefault: true - name: TeslaMate type: grafana-postgresql-datasource uid: TeslaMate url: pg-teslamate-rw.teslamate.svc.cluster.local:5432 database: teslamate user: teslamate access: proxy isDefault: false editable: true secureJsonData: password: $__env{TESLAMATE_DB_PASSWORD} jsonData: sslmode: disable postgresVersion: 1600 timescaledb: false database: teslamate # --- Sidecar to auto-discover dashboards from ConfigMaps --- # Dashboards are deployed as ConfigMaps with the label grafana_dashboard: "1" # The sidecar automatically discovers them and loads them into Grafana containerSecurityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL sidecar: dashboards: enabled: true label: grafana_dashboard labelValue: "1" folder: /var/lib/grafana/dashboards searchNamespace: ALL defaultFolderName: "General" provider: foldersFromFilesStructure: true