Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Command to export all grafana 2 dashboard to JSON using curl
KEY=XXXXXXXXXXXX
HOST="https://metrics.crisidev.org"
mkdir -p dashboards && for dash in $(curl -k -H "Authorization: Bearer $KEY" $HOST/api/search\?query\=\& |tr ']' '\n' |cut -d "," -f 5 |grep slug |cut -d\" -f 4); do
curl -k -H "Authorization: Bearer $KEY" $HOST/api/dashboards/db/$dash > dashboards/$dash.json
done
@elekgeek
Copy link

elekgeek commented May 23, 2020

mmmm... which script to use :D

@ssh2n
Copy link

ssh2n commented Jun 16, 2020

hi, I tried the one from @magiconair (this one) which is working pretty well so far,
but I have some issues...

on importing it to another grafana instance (like copypaste content of the exportet .json file on import via GUI)

  • all variables are gone
  • cant select datasource(s) on import (cause __requires section is missing and )
  • and even the title seems to be away on import
    (even though the name is on the bottom of the .json - as title! )
    "timezone": "",
    "title": "My Fancy Dashboard",
    "uid": "tH3uId",
    "variables": {
      "list": []

any suggestions, how to export all dashboards (at once) formatted like the ones you get by clicking "Download JSON" on https://grafana.com/grafana/dashboards ? =P

thanks in advance & best regards :)

@sshaikh
Copy link

sshaikh commented Aug 18, 2020

fwiw some versions of jq have a "feature" that breaks pipes. If you;re having trouble, make sure you use jq . -r when piping.

@evanstucker-hates-2fa
Copy link

evanstucker-hates-2fa commented Sep 22, 2020

Yet another iteration of this idea:

#!/bin/bash

# Usage:
#
# export_grafana_dashboards.sh https://admin:REDACTED@grafana.dedevsecops.com

create_slug () {
  echo "$1" | iconv -t ascii//TRANSLIT | sed -r s/[^a-zA-Z0-9]+/-/g | sed -r s/^-+\|-+$//g | tr A-Z a-z
}

full_url=$1
username=$(echo "${full_url}" | cut -d/ -f 3 | cut -d: -f 1)
base_url=$(echo "${full_url}" | cut -d@ -f 2)
folder=$(create_slug "${username}-${base_url}")

mkdir "${folder}" 
for db_uid in $(curl -s "${full_url}/api/search" | jq -r .[].uid); do
  db_json=$(curl -s "${full_url}/api/dashboards/uid/${db_uid}")
  db_slug=$(echo "${db_json}" | jq -r .meta.slug)
  db_title=$(echo "${db_json}" | jq -r .dashboard.title)
  filename="${folder}/${db_slug}.json"
  echo "Exporting \"${db_title}\" to \"${filename}\"..." 
  echo "${db_json}" | jq -r . > "${filename}"
done
echo "Done"

@mator
Copy link

mator commented Nov 23, 2020

Can someone patch grafana-cli to export dashboards to a single (as a most simple task) JSON ? :)

@chipironcin
Copy link

chipironcin commented Jan 14, 2021

Used @magiconair script with a slight modification to use username/password and a fix to the second 'jq' call.
Worked fine with Grafana 6.7.2.
To import the dashboard (one by one) use the import tool from Grafana. Paste everything under the "dashboard" object and delete properties "version" and "uid".

Here's the modified script and a container I ran this into.

#!/bin/bash

set -o errexit
set -o pipefail

HOST="grafana.tools.connected.dyson.cloud"
FULLURL="https://<username>:<password>@$HOST"

set -o nounset

echo "Exporting Grafana dashboards from $HOST"
rm -rf dashboards
mkdir -p dashboards
for dash in $(curl -s "$FULLURL/api/search?query=&" | jq -r '.[] | select(.type == "dash-db") | .uid'); do
        curl -s "$FULLURL/api/dashboards/uid/$dash" | jq -r . > dashboards/${dash}.json
        slug=$(cat dashboards/${dash}.json | jq -r '.meta.slug')
        mv dashboards/${dash}.json dashboards/${dash}-${slug}.json
done
docker run -it -v $(pwd):/myfolder -w "/myfolder" --rm bitnami/minideb bash
install_packages curl ca-certificates jq
chmod +x exportGrafana.sh
./exportGrafana.sh

@jbritt1
Copy link

jbritt1 commented Feb 18, 2021

Do any of these scripts work when your Grafana deployment has folders of dashboards? Tried a couple different iterations and wind up with the <folderName>.json (when cat'd returns "Dashboard not found" of course) and then not having the dashboards inside said folder.

@renatosis
Copy link

renatosis commented Jun 4, 2021

Hi all. In order to make the exported dashboards "importable" I had to remove the "dashboard" object that was including the dashboard itself. The json included a meta and a dashboard objects. Please change the 2nd jq to the example below to make it work:

FROM:
jq -r . > dashboards/${dash}.json

TO:
jq -r {meta:.meta}+.dashboard > dashboards/${dash}.json

I hope it helps!!!

@Cililing
Copy link

Cililing commented Jun 9, 2021

I had an issue with making a script because in my randomly generated auth password there were chars like :, ;, &.

So, using curl -s http://admin:passwd@localhost:3000 wasn't working.
The simplest solution I found (without double-quote-hell) was using the -u parameter in curl, like below:

AUTH="admin:passwd"
API_BASE="http://localhost:3000"
...
curl -s -u "${AUTH}" "${API_BASE}/api/search" 

@varac
Copy link

varac commented Jun 15, 2021

Do any of these scripts work when your Grafana deployment has folders of dashboards? Tried a couple different iterations and wind up with the <folderName>.json (when cat'd returns "Dashboard not found" of course) and then not having the dashboards inside said folder.

Yes. I just successfully exported all my dashboards with the latest script from https://gist.github.com/crisidev/bd52bdcc7f029be2f295#gistcomment-3593795, and I have different dashboard folders.

@varac
Copy link

varac commented Jun 15, 2021

Well, I succeeded exporting them but I re-importing resulted in an empty dashboard (grafana 7.5.5) :/

@Ruksaaar
Copy link

Ruksaaar commented Jun 28, 2021

Hey @varac any luck importing them?

@varac
Copy link

varac commented Jun 28, 2021

Hey @varac any luck importing them?

No - I ended up exporting + reimporting manually :/

@Ruksaaar
Copy link

Ruksaaar commented Jun 29, 2021

Hello,
I tried to run something on my own to see if the dashboards get imported all at once or not. Below short script worked for me. I used @magiconair 's script to export the dashboards to my system.

for FILE in *; do
cat $FILE | jq '. * {overwrite: true, dashboard: {id: null}}' | curl -X POST
-H "Content-Type: application/json" -H "Authorization: Bearer api-key-with-write-permissions"
grafana-url/api/dashboards/db -d @- ;
done

With this all the dashboards are re-imported on grafana.

I hope it helps.

P.S - The code was taken with the help from https://github.com/monitoringartist/grafana-utils

@jmorcar
Copy link

jmorcar commented Aug 19, 2021

Only is for dashboards, with datasource the command is failed:

#ERROR indicating id (basename file) in XPUT :
cat VSPP/datasources/VSPP.json.json | jq '. * {overwrite: true }' | curl -k -XPUT -H "Content-Type: application/json" -H "Accept: application/json" -H "Authorization: Basic aaaaaaaa" http://localhost:3000/api/datasources/VSPP.json -d @-

result:
{"message":"Failed to update datasource. Reload new version and try again"}

#WITHOUT JQ {overwrite: true } - json datasource exported without changes:
$ cat "VSPP/datasources/VSPP.json.json" | curl -k -XPUT -H "Content-Type: application/json" -H "Accept: application/json" -H "Authorization: Basic aaaaaaaa" http://localhost:3000/api/datasources/VSPP.json -d @-

result:
{"message":"Failed to update datasource. Reload new version and try again"}

Any idea about how to import datasources ??? I try to import from export json files like (when datasource already exist - I need update the version of datasource or overwrite it )

{
  "id": 39,
  "orgId": 6,
  "name": "VSPP",
  "type": "graphite",
  "typeLogoUrl": "",
  "access": "proxy",
  "url": "http://1.1.1.1:8066",
  "password": "",
  "user": "",
  "database": "",
  "basicAuth": true,
  "basicAuthUser": "***",
  "basicAuthPassword": "****",
  "withCredentials": false,
  "isDefault": true,
  "jsonData": {
    "graphiteVersion": "",
    "keepCookies": []
  },
  "secureJsonFields": {},
  "version": 5,
  "readOnly": false
}

@autokilla47
Copy link

autokilla47 commented Oct 14, 2021

It is work! All Orgs with folders are saved. Thanks @xmsanchez for base scripts and @renatosis for 'jq'. Grafana ver 7.5.4:


#!/bin/bash

HOST='http://localhost:3000'
DASH_DIR=/path/to/dir

# Declare a list with the api keys using as a prefix the organization name plus "_" character
declare -a StringArray=("MAIN_<api-key>" "OtherOrg_<api-key>" "YetOnAnother_<api-key>")

# Iterate through api keys:
for API_KEY in "${StringArray[@]}"; do
    ORG=$(echo $API_KEY | cut -d "_" -f1) # Name of the organization based on the prefix
    KEY=$(echo $API_KEY | cut -d "_" -f2) # API Key for that organization after removing the prefix

    # Iterate through dashboards using the current API Key
    for dashboard_uid in $(curl -sS -H "Authorization: Bearer $KEY" $HOST/api/search\?query\=\& | jq -r '.[] | select( .type | contains("dash-db")) | .uid'); do
        url=`echo $HOST/api/dashboards/uid/$dashboard_uid | tr -d '\r'`
        dashboard_json=$(curl -sS -H "Authorization: Bearer $KEY" $url)
        dashboard_title=$(echo $dashboard_json | jq -r '.dashboard | .title' | sed -r 's/[ \/]+/_/g' )
        dashboard_version=$(echo $dashboard_json | jq -r '.dashboard | .version')
        folder_title="$(echo $dashboard_json | jq -r '.meta | .folderTitle')"

        # You can export the files like this to keep them organized by organization:
        mkdir -p "$DASH_DIR/$ORG/$folder_title/dashboards_$ORG"
        echo $dashboard_json | jq -r {meta:.meta}+.dashboard  > $DASH_DIR/$ORG/$folder_title/dashboards_$ORG/${dashboard_title}_v${dashboard_version}.json
    done
done

@farukhkhan123
Copy link

farukhkhan123 commented Nov 23, 2021

Solution provided by @autokilla47 works fine for exporting out of Grafana. However, if you want to export the dashboards between different servers/deployments/foundations (SB/NP,PROD) via api "api/dashboards/import", ID key needs to be "null" to allow the dashboard import. However if you run another import, even with overwrite set to "true" you get the following error
{
"message": "The dashboard has been changed by someone else",
"status": "version-mismatch"
}

@chan-vince
Copy link

chan-vince commented Nov 26, 2021

Solution provided by @autokilla47 works fine for exporting out of Grafana. However, if you want to export the dashboards between different servers/deployments/foundations (SB/NP,PROD) via api "api/dashboards/import", ID key needs to be "null" to allow the dashboard import. However if you run another import, even with overwrite set to "true" you get the following error { "message": "The dashboard has been changed by someone else", "status": "version-mismatch" }

I had that issue too - instead I used the /api/dashboards/db endpoint. I still had to set the id to null, but it seems I don't get the overwrite error you have.
See my example in python: https://github.com/Beam-Connectivity/grafana-dashboard-manager

@farukhkhan123
Copy link

farukhkhan123 commented Dec 15, 2021

@chan-vince I think the Version number is causing this "version-mismatch" problem i.e for a brand new dashboard, version is 1 in both SB and Non-Prod foundations after the initial successful export. Then, I went ahead and added multiple changes and saved dashboard after each change, now version in SB is 4, but never exported versions 2 & 3 to Non-Prod. When i export the dashboard from SB, even though i am resetting the ID to null with overwrite true. it still runs into this problem "version-mismatch" because i am trying to overwrite version 1 with 4, it appears to want the exact version number already deployed in Non-prod to increment it with 1.

@tedraymond
Copy link

tedraymond commented Jan 4, 2022

This is awesome. The only addition I had was adding or removing the -k flag to curl depending if the Grafana instance was http or https. Thansk for sharing.

@kaladhar-mummadi
Copy link

kaladhar-mummadi commented Feb 19, 2022

Used @chipironcin to create dashboards in folders

KEY="my_key_here"
HOST="https://my_instance.com"

GRAFANA_DASHBOARDS_FOLDER=".grafana/dashboards"
echo "Exporting Grafana dashboards from $HOST"
mkdir -p "${GRAFANA_DASHBOARDS_FOLDER}"
for dash in $(curl -sSL -k -H "Authorization: Bearer ${KEY}" "${HOST}/api/search?query=&" | jq -r '.[] | select(.type == "dash-db") | .uid'); do
  curl -sSL -k -H "Authorization: Bearer ${KEY}" "${HOST}/api/dashboards/uid/$dash" | jq -r . >${GRAFANA_DASHBOARDS_FOLDER}/${dash}.json
  slug=$(cat ${GRAFANA_DASHBOARDS_FOLDER}/${dash}.json | jq -r '.meta.slug')
  folder=$(cat ${GRAFANA_DASHBOARDS_FOLDER}/${dash}.json | jq -r '.meta.folderTitle')
  mkdir -p "${GRAFANA_DASHBOARDS_FOLDER}/${folder}"
  mv ${GRAFANA_DASHBOARDS_FOLDER}/${dash}.json "${GRAFANA_DASHBOARDS_FOLDER}/${folder}/${slug}.json"
done

@KMurphs
Copy link

KMurphs commented Jun 11, 2022

I used this to export dashboards and datasources

#!/usr/bin/env bash

# SOURCE VARIABLES
export token=xxxxx#admin token
export grafanaurl=http://xxx.xxx.xxx.xxx:3000/api


rm -rf backups
mkdir -p backups
cd backups



datasources=$(curl -s -H "Authorization: Bearer $token" -X GET $grafanaurl/datasources)
for uid in $(echo $datasources | jq -r '.[] | .uid'); do
  uid="${uid/$'\r'/}" # remove the trailing '/r'
  curl -s -H "Authorization: Bearer $token" -X GET "$grafanaurl/datasources/uid/$uid" | jq > grafana-datasource-$uid.json
  slug=$(cat grafana-datasource-$uid.json | jq -r '.name')
  mv grafana-datasource-$uid.json grafana-datasource-$uid-$slug.json # rename with datasource name and id
  echo "Datasource $uid exported"
done



dashboards=$(curl -s -H "Authorization: Bearer $token" -X GET $grafanaurl/search?folderIds=0&query=&starred=false)
for uid in $(echo $dashboards | jq -r '.[] | .uid'); do
  uid="${uid/$'\r'/}" # remove the trailing '/r'
  curl -s -H "Authorization: Bearer $token" -X GET "$grafanaurl/dashboards/uid/$uid" | jq > grafana-dashboard-$uid.json
  slug=$(cat grafana-dashboard-$uid.json | jq -r '.meta.slug')
  mv grafana-dashboard-$uid.json grafana-dashboard-$uid-$slug.json # rename with dashboard name and id
  echo "Dashboard $uid exported"
done



# https://www.ifconfig.it/hugo/2021/12/backup-grafana-dashboards-with-api-and-jq/
# https://gist.github.com/crisidev/bd52bdcc7f029be2f295

And i used this to re-import all dashboards and datasources on my second server.
Obviously, datasources are exported without passwords, and although the script below will re-import them, you have to manually re-set the datasource passwords.

#!/usr/bin/env bash

# DESTINATION VARIABLES
export token=xxxxxx #admin token
export grafanaurl=http://xxx.xxx.xxx.xxx:3000/api


cd backups



for FILE in *dashboard*; do
  echo Importing Dashboard: $FILE
  cat $FILE | jq '. * {overwrite: true, dashboard: {id: null}}' | curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" "$grafanaurl/dashboards/db" -d @- ;
done



for FILE in *datasource*; do
  echo Importing Dashboard: $FILE
  cat $FILE | curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" "$grafanaurl/datasources/" -d @- ;
done



# https://www.ifconfig.it/hugo/2021/12/backup-grafana-dashboards-with-api-and-jq/
# https://gist.github.com/crisidev/bd52bdcc7f029be2f295

@ethsol
Copy link

ethsol commented Jun 30, 2022

We also needed to export Grafana dashboards, tried the code posted by @KMurphs (thanks) but it only exported some but not all of the dashboards, so changed the code a bit.

#!/usr/bin/env bash

#SOURCE VARIABLES
export token=xxxxx#admin token
export grafanaurl=http://xxx.xxx.xxx.xxx:3000/api

#rm -rf backup
BACKUPDIR=backup_$(date +%Y%m%d_%H%M)
mkdir -p $BACKUPDIR
cd $BACKUPDIR

datasources=$(curl -s -H "Authorization: Bearer $token" -X GET $grafanaurl/datasources)
for uid in $(echo $datasources | jq -r '.[] | .uid'); do
  uid="${uid/$'\r'/}" # remove the trailing '/r'
  curl -s -H "Authorization: Bearer $token" -X GET "$grafanaurl/datasources/uid/$uid" | jq > grafana-datasource-$uid.json
  slug=$(cat grafana-datasource-$uid.json | jq -r '.name')
  mv grafana-datasource-$uid.json grafana-datasource-$uid-$slug.json # rename with datasource name and id
  echo "Datasource $uid exported"
done

#dashboards=$(curl -s -H "Authorization: Bearer $token" -X GET $grafanaurl/search?folderIds=0&query=&starred=false)
dashboards=$(curl -s -H "Authorization: Bearer $token" -X GET $grafanaurl/search)
for uid in $(echo $dashboards | jq -r '.[] | .uid'); do
  uid="${uid/$'\r'/}" # remove the trailing '/r'
  curl -s -H "Authorization: Bearer $token" -X GET "$grafanaurl/dashboards/uid/$uid" | jq > grafana-dashboard-$uid.json
  slug=$(cat grafana-dashboard-$uid.json | jq -r '.meta.slug')
  mv grafana-dashboard-$uid.json grafana-dashboard-$uid-$slug.json # rename with dashboard name and id
  echo "Dashboard $uid exported"
done

cd ..

# https://www.ifconfig.it/hugo/2021/12/backup-grafana-dashboards-with-api-and-jq/
# https://gist.github.com/crisidev/bd52bdcc7f029be2f295```

@senz
Copy link

senz commented Jul 28, 2022

Yet another iteration with folders structure, and token auth
usage ./export.sh https://grafana.local MY_API_TOKEN

#!/bin/bash

set -o errexit
set -o pipefail
set -x

FULLURL="$1"
headers="Authorization: Bearer $2"
in_path=dashboards_raw
set -o nounset

echo "Exporting Grafana dashboards from $FULLURL"
mkdir -p $in_path
for dash in $(curl -H "$headers" -s "$FULLURL/api/search?query=&" | jq -r '.[] | select(.type == "dash-db") | .uid'); do
        dash_path="$in_path/$dash.json"
        curl -H "$headers" -s "$FULLURL/api/dashboards/uid/$dash" | jq -r . > $dash_path
        slug=$(cat $dash_path | jq -r '.meta.slug')
        folder="$(cat $dash_path | jq -r '.meta.folderTitle')"
        mkdir -p "$folder"
        mv -f $dash_path $folder/${dash}-${slug}.json
done

@prcdpr
Copy link

prcdpr commented Aug 4, 2022

@senz
Dashboard folders can have spaces, so replace second to last line with

mv -f $dash_path "$folder/${dash}-${slug}.json"

@merlian2
Copy link

merlian2 commented Aug 15, 2022

Quick Question @senz

How do you import with the folder structure?

@fooblahblah
Copy link

fooblahblah commented Aug 23, 2022

Hi all. In order to make the exported dashboards "importable" I had to remove the "dashboard" object that was including the dashboard itself. The json included a meta and a dashboard objects. Please change the 2nd jq to the example below to make it work:

FROM: jq -r . > dashboards/${dash}.json

TO: jq -r {meta:.meta}+.dashboard > dashboards/${dash}.json

I hope it helps!!!

This did help my situation on Grafana 8.3.3 to 8.5.2

@mintuguptha
Copy link

mintuguptha commented Aug 30, 2022

@merlian2 did you got the solution to import dashboards in folder structure ??

@GreenieT87
Copy link

GreenieT87 commented Sep 26, 2022

Also needed to export a bunch of Dashboards adjusted the code of @senz a bit to get the proper dashboard names as the filename and to get rid of the dashboards_raw folder.

#!/bin/bash

set -o errexit
set -o pipefail
# set -x

FULLURL="$1"
headers="Authorization: Bearer $2"
in_path=dashboards_raw
set -o nounset

echo "Exporting Grafana dashboards from $FULLURL"
mkdir -p $in_path
for dash in $(curl -H "$headers" -s "$FULLURL/api/search?query=&" | jq -r '.[] | select(.type == "dash-db") | .uid'); do
        curl -H "$headers" -s "$FULLURL/api/search?query=&" 1>/dev/null
        dash_path="$in_path/$dash.json"
        curl -H "$headers" -s "$FULLURL/api/dashboards/uid/$dash" | jq -r . > $dash_path 
        jq -r .dashboard $dash_path > $in_path/dashboard.json 
        title=$(jq -r .dashboard.title $dash_path)
        folder="$(jq -r '.meta.folderTitle' $dash_path)"
        mkdir -p "$folder"
        mv -f $in_path/dashboard.json "$folder/${title}.json"
       echo "exported $folder/${title}.json"
       
done
rm -r $in_path

@merlian2 @mintuguptha To import with folder structure, I make use of dashboard provisioning. See Grafana Docs

@sastorsl
Copy link

sastorsl commented Oct 3, 2022

    mkdir -p "$folder"

@GreenieT87 I had sub folders, so I made the following diff to your script.
Feel free to edit your post if you wish.

21c21,26
<         mkdir -p "$folder"
---
>         if [[ $title =~ / ]]
>         then
>             mkdir -p "$folder/${title%/*}"
>         else
>             mkdir -p "$folder"
>         fi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment