How to upload dashboards as .json files to kubernetes via helm

Hi all,
I have installed grafana helm chart, and want to pass values to it from a parent chart - i am using prometheus in this way so assume it will also be possible. My directory structure is;

/grafana
   /charts/grafana-6.16.10.tgz
   /dashboards/kubernetes.json
   /values.yaml
   /datasources.yaml

In the values.yaml have;

grafana:
  dashboardProviders:
   dashboardproviders.yaml:
     apiVersion: 1
     providers:
     - name: 'default'
       orgId: 1
       folder: ''
       type: file
       disableDeletion: false
       editable: true
       options:
         path: /var/lib/grafana/dashboards/default

  dashboards:
    default:
      kubernetes:
        file: dashboards/kubernetes.json
      azure:
        gntId: 14986
        version: 1

When running the helm upgrade, it picks up my values.yaml and creates a /var/lib/grafana/dashboards/default directory, however the kubernetes.json it loads is empty, and I get the following error in the log;

lvl=eror msg="failed to load dashboard from " logger=provisioning.dashboard type=file name=default file=/var/lib/grafana/dashboards/default/kubernetes.json error=EOF

Looking through the go code, I can see that it will create a .json if the value is .json, which explains why the empty file is being created.

I’ve also read that it is currently not possible to pass dashboards ‘externally’ to the chart, even though we are able to pass datasources.yaml ‘externally’. We generate this file using a shell script.

The other suggestion has been to use a sidecar, however in the halm chart default values, the following is written;

## Sidecars that collect the configmaps with specified label and stores the included files them into the respective folders
## Requires at least Grafana 5 to work and can't be used together with parameters dashboardProviders, datasources and dashboards

I do not want to configure our datasources using sidecar, only the dashboards. Does this mean this option is not available to me? I’m at an impasse now, any guidance would be very much appreciated.

Thank you!
Swapna

1 Like

I’ve managed to get dashboards loading with the following config;

  • create a grafana/values.yaml
grafana:
  dashboardProviders:
   dashboardproviders.yaml:
     apiVersion: 1
     providers:
     - name: 'default'
       orgId: 1
       folder: ''
       type: file
       disableDeletion: false
       editable: true
       options:
         path: /var/lib/grafana/dashboards/default

  dashboardsConfigMaps:
    default: "grafana-dashboards"
  • create a grafana/templates/grafana-dashboard-configmap.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: grafana-dashboards
  labels:
    grafana_dashboard: "1"
data:
  kubernetes.json: |
{{ .Files.Get "grafana-dashboards/kubernetes.json" | indent 4 }}
  • copy the dashboard json to grafana/grafana-dashboards/kubernetes.json
  • run helm upgrade --install grafana as normal

This will load the configmap from the template in the parent directory, and thus will be able to find the dashboard in the parent folder grafana-dashboards.

Simple really when you know how! Not sure if anyone is reading this but hope it helps…

4 Likes

This works as well and is much simpler:

grafana:
  dashboardProviders:
   dashboardproviders.yaml:
     apiVersion: 1
     providers:
     - name: 'default'
       orgId: 1
       folder: ''
       type: file
       disableDeletion: false
       editable: true
       options:
         path: /var/lib/grafana/dashboards/default

  dashboards:
    default:
      kubernetes:
        json: |
          ${indent(8, file("${path.module}/dashboards/kubernetes.json"))}
      azure:
        gntId: 14986
        version: 1
1 Like

Thank you, I will give that a go, however could you please explain what ${path.module} refers to and where the kubernetes.json dashboard needs to reside?

Hi
Can also someone help me to place dashboards that were uploaded through configmap ?
I need to place them in the folder described in dashboardproviders

Currently, my provider looks like this

dashboardProviders:
    dashboardproviders.yaml:
      apiVersion: 1
      providers:
      - name: "infra-dashboards"
        orgId: 1
        folder: 'Infra'
        type: file
        disableDeletion: true
        allowUiUpdates: true
        options:
          path: /tmp/dashboards/grafana-dashboards
dashboardsConfigMaps:
  infra-dashboards: "grafana-dashboards"

The folder was created, dashboards also appeared but in the Default folder not it Infra folder.

Can someone tell me what I’m doing wrong?

${path.module} is an expression from Terraform

path.module is the filesystem path of the module where the expression is placed.

If you want, instead of

${path.module}/dashboards/kubernetes.json

you can use

./dashboards/kubernetes.json

You gonna loose some level of portability but it still gonna work

The path is incorrect. From the helm chart itself you can read:

Configure grafana dashboard providers
ref: Provisioning | Grafana Labs
path must be /var/lib/grafana/dashboards/<provider_name>

https://github.com/grafana/helm-charts/blob/main/charts/grafana/values.yaml

Try to copy-paste examples from the documentation. Check whether it works for you and then modify it for your needs.

1 Like

Thanks, I think I had tried that originally but the issue was that that path, either of;

dashboards/kubernetes.json
./dashboards/kubernetes.json

is referred from within the child helm chart rather than the parent chart, and I did not want to store my dashboards there as that helm chart is zipped up and therefore difficult to PR. So the only way I could get the parent chart to pick up dashboards was to configure them as configmaps.

Appreciate your assistance!

What if you want to upload multiple dashboards, is there a way to do this?
This approach works for just one dashboard, but it would be nice if one was able to upload several into one folder.

Any ideas anyone, please?

I’m using Terraform and I found a way to upload multiple dashboards building on @rafzukow 's answer.

Create a folder with the json files in it at the root of the Terraform module - I called it “custom_dashboards”.

Make the values file a Terraform template with a .tftpl suffix.

Use the helm_release provider to create the installation - I used kube-prometheus-stack with grafana as a subchart:

resource "helm_release" "monitoring" {
  name  = "prometheus"
  repository = "https://prometheus-community.github.io/helm-charts"
  chart = "kube-prometheus-stack"
  namespace = "monitoring"
  values  = [templatefile("${path.module}/helm/prometheus-values.tftpl", {
    custom_dashboards = fileset("${path.module}/custom_dashboards/", "*.json"),
    module_path = path.module
  })]
}

Then in the template file under the Grafana values under the dashboardProviders key:
prometheus-values.tftpl

  dashboardProviders:
    dashboardproviders.yaml:
      apiVersion: 1
      providers:
      - name: 'default'
        orgId: 1
        folder: ''
        type: file
        disableDeletion: true
        editable: true
        options:
          path: /var/lib/grafana/dashboards/default
  dashboards:
    default:
      %{ for dashboard in custom_dashboards ~}
${indent(4, replace(replace(dashboard, ".json", ""), "./", ""))}:
        json: |
          ${indent(8, file("${module_path}/custom_dashboards/${dashboard}"))}
      %{ endfor }

This way Terraform will dynamically pick up the json files in the directory and load them into the values file. I left folder blank since I want them to go into my General folder, however it should work if you specify a value there to get them in a separate folder.

2 Likes