Grafana helm & postgres example

From UVOO Tech Wiki
Jump to navigation Jump to search

Simple Example of Grafana with Postgres Backend

This should get you pretty close to what you want

Configs

Grafana

override.values.yaml.envsubst

image:
  repository: grafana/grafana
  # Overrides the Grafana image tag whose default is the chart appVersion
  # tag: 10.3.3
  # sha256: f8f7d338b2ecd278599e7f1cfc84a0a7bd4f549312218a54696edb38d709100d
  pullPolicy: IfNotPresent

replicas: 1

ingress:
  enabled: true
  ingressClassName: nginx
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  labels: {}
  path: /

  pathType: Prefix

  hosts:
    - grafana${DOT_ENV_NAME}.example.com
  tls:
    - secretName: grafana${DASH_ENV_NAME}-example-com
      hosts:
        - grafana${DOT_ENV_NAME}.example.com

persistence:
  type: pvc
  enabled: false
  # storageClassName: default
  accessModes:
    - ReadWriteOnce
  size: 10Gi
  # annotations: {}
  finalizers:
    - kubernetes.io/pvc-protection
  extraPvcLabels: {}
  inMemory:
    enabled: true
    ## The maximum usage on memory medium EmptyDir would be
    ## the minimum value between the SizeLimit specified
    ## here and the sum of memory limits of all containers in a pod
    ##
    sizeLimit: 900Mi

initChownData:
  enabled: true
  image:
    repository: busybox
    tag: "1.31.1"
    sha: ""
    pullPolicy: IfNotPresent

  securityContext:
    runAsNonRoot: false
    runAsUser: 0

# Administrator credentials when not using an existing secret (see below)
adminUser: admin
adminPassword: ${GF_SECURITY_ADMIN_PASSWORD}

# Use an existing secret for the admin user.
admin:
  existingSecret: ""
  userKey: admin-user
  passwordKey: admin-password
#
# admin:
#   existingSecret: "grafana-external-secrets"

grafana.ini:
  paths:
    data: /var/lib/grafana/
    logs: /var/log/grafana
    plugins: /var/lib/grafana/plugins
    provisioning: /etc/grafana/provisioning
  analytics:
    check_for_updates: true
  log:
    mode: console
  grafana_net:
    url: https://grafana.net
  server:
    domain: "{{ if (and .Values.ingress.enabled .Values.ingress.hosts) }}{{ .Values.ingress.hosts | first }}{{ else }}''{{ end }}"
  auth.ldap:
    enabled: true
    allow_sign_up: true
    config_file: /etc/grafana/ldap.toml
  smtp:
    enabled: true
    user: ""
    host: "${SMTP_RELAY_HOST}"
    fromAddress: "noreply-grafana@example.com"
    fromName: ""
    skipVerify: "false"
    existingSecret: ""
    startTLS_policy: "NoStartTLS"
    existingSecretUserKey: user
    existingSecretPasswordKey: password
  alerting:
    enabled: false
  unified_alerting:
    enabled: true
    rule_version_record_limit: "5"
    ha_peers: "grafana-headless:9094"
    # ha_listen_address: "${POD_IP}:9094"      # not needed, defaults to 0.0.0.0:9094
    # ha_advertise_address: "${POD_IP}:9094"   # not needed, defaults to your listen address
    # ha_peers: "{{ .Release.Name }}-headless:9094"

headlessService: true

ldap:
  enabled: true
external-secrets
  # existingSecret: ""
  config: |-
    [[servers]]
    host = "ldaps.example.com"
    bind_dn = "CN=grafana-ldap,OU,OU=service_accounts,DC=example,DC=com"
    bind_password = "${SVC_GRAFANA_LDAP_PASSWORD}"
    port = 636
    use_ssl = true
    start_tls = false
    ssl_skip_verify = false
    # Use if direct connect: bind_dn = "example\\%s"
    search_filter = "(sAMAccountName=%s)"
    search_base_dns = ["dc=example,dc=com"]
    root_ca_cert = "/etc/grafana/certs/ca.crt"

    [servers.attributes]
    name = "givenName"
    surname = "sn"
    username = "sAMAccountName"
    member_of = "memberOf"
    email =  "mail"

    [[servers.group_mappings]]
    group_dn = "CN=grafana_editor_role,OU=roles,DC=Example,DC=com"
    org_role = "Editor"

    [[servers.group_mappings]]
    group_dn = "CN=grafana_admin_role,OU=roles,DC=Example,DC=com"
    org_role = "Admin"

    [[servers.group_mappings]]
    group_dn = "*"
    org_role = "Viewer"

## Grafana's SMTP configuration
## NOTE: To enable, grafana.ini must be configured with smtp.enabled
## ref: http://docs.grafana.org/installation/configuration/#smtp
smtp:
  # `existingSecret` is a reference to an existing secret containing the smtp configuration
  # for Grafana.
  existingSecret: ""
  userKey: "user"
  passwordKey: "password"

envFromSecrets:
  - name: grafana-env
    optional: false

envFromConfigMaps:
  - name: grafana-env
    optional: false
extraConfigmapMounts:
  - name: certs
    mountPath: /etc/grafana/certs/ca.crt
    subPath: ca.crt
    configMap: certs
    readOnly: true
  - name: etc-ssl-certs
    mountPath: /etc/ssl/certs/ca-certificates.crt
    subPath: ca-certificates.crt
    configMap: etc-ssl-certs
    readOnly: true

Postgres

pg1.yaml

  instances: 2
  imageName: ghcr.io/cloudnative-pg/postgresql:17.5-bookworm
  primaryUpdateStrategy: unsupervised      # automated rolling update (default)
  primaryUpdateMethod: switchover          # promote a fully-upgraded replica

  postgresql:
    parameters:
      shared_buffers: 512MB

  storage:
    size: 10Gi

  # bootstrap:
  #   recovery:
  #     source: test

  # backup:
  #   retentionPolicy: "30d"
  #   barmanObjectStore:
  #     destinationPath: "https://myblobstorageaccount.blob.core.windows.net/grafana/cnpg-backups/"
  #     azureCredentials:
  #       storageAccount:
  #         name: cnpg-storage-blob-creds
  #         key: AZURE_STORAGE_ACCOUNT
  #       storageKey:
  #         name: cnpg-storage-blob-creds
  #         key: AZURE_STORAGE_KEY

secrets.yaml.tpl

---
apiVersion: v1
kind: Secret
metadata:
  name: grafana-env
  labels:
    app: grafana
stringData:
  GF_DATABASE_PASSWORD: {{ GF_DATABASE_PASSWORD }}
  GF_SECURITY_ADMIN_PASSWORD: {{ GF_SECURITY_ADMIN_PASSWORD }}
# ---
# apiVersion: v1
# stringData:
#   user: $SMTP_RELAY_USERNAME
#   password: $SMTP_RELAY_USERPASS
# kind: Secret
# metadata:
#   name: grafana-smtpauth
#   labels:
#     app: grafana

configmaps.yaml

---
apiVersion: v1
data:
  GF_SERVER_ROOT_URL: "https://grafana{{ ENV_URL_INFIX }}example.com"
  GF_DEFAULT_INSTANCE_NAME: default
  GF_SECURITY_ADMIN_USER: admin
  GF_DATABASE_TYPE: postgres
  GF_DATABASE_HOST: {{ GF_DATABASE_HOST }}
  GF_DATABASE_NAME: {{ GF_DATABASE_NAME }}
  GF_DATABASE_USER: {{ GF_DATABASE_USER }}
  GF_INSTALL_PLUGINS: grafana-piechart-panel
  GF_DATABASE_SSL_MODE: "disable"
  # GF_DATABASE_SSL_MODE: require
  # GF_DATABASE_SSL_MODE: verify-full
  GF_INSTALL_PLUGINS: briangann-datatable-panel,michaeldmoore-annunciator-panel,btplc-status-dot-panel, natel-discrete-panel, natel-influx-admin-panel, grafana-clock-panel, savantly-heatmap-panel, grafana-piechart-panel, snuids-trafficlights-panel, jdbranham-diagram-panel, xginn8-pagerduty-datasource, yesoreyeram-infinity-datasource
  GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS: "grafana-piechart-panel, grafana-sensu-app, btplc-status-dot-panel, grafana-app-sensu-overview-panel, sensu-sensugo-datasource, grafana-sensucore-datasource, briangann-datatable-panel"
kind: ConfigMap
metadata:
  name: grafana-env
  labels:
    app: grafana
---
apiVersion: v1
data:
  ca.crt: |
    -----BEGIN CERTIFICATE-----
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    -----END CERTIFICATE-----
kind: ConfigMap
metadata:
  name: certs

main.sh

#!/bin/bash
set -eu
. ../includes/main.sh

update_ca_trust_configmap(){
  kubectl apply -f <(kubectl create configmap etc-ssl-certs --from-file=ca-certificates.crt=./etc-ssl-certs/ca-certificates.crt --dry-run=client -o yaml)
}
update_ca_trust_configmap

envtpl --keep-template aks-secret-provider.yaml.tpl
kubectl_apply "-f aks-secret-provider.yaml"
kubectl_apply "-f aks-secret-provider-mnt.yaml"

# Example for blob backups but we have scheduled job for backups for simplicity
# tfile=cnpg-storage-blob-creds.secret.yaml
# envtpl --keep-template ../tpls/$tfile.tpl -o $tfile
# kubectl_apply "-f $tfile"

kubectl_apply "-f pg1.yaml"

envtpl --keep-template secrets.yaml.tpl
kubectl_apply "-f secrets.yaml"

envtpl --keep-template configMaps.yaml.tpl
kubectl_apply "-f configmaps.yaml"

envsubst < values.yaml.envsubst > values.yaml
helm_upgrade "--install --version 9.2.9 grafana grafana/grafana -f values.yaml"