Grafana Dashboards Backup
This role backs up all Grafana dashboards using the Grafana API to dual NAS storage.
Grafana Dashboards Backup Role
Overview
This role backs up all Grafana dashboards using the Grafana API to dual NAS storage. It downloads dashboard JSON definitions, creates compressed archives, and automatically manages retention by keeping only the last 5 backups per NAS. The exported JSON format is compatible with Grafana’s import functionality.
Purpose
- Disaster Recovery: Protect dashboard configurations against data loss
- Version Control: Maintain timestamped history of dashboard changes
- Migration: Transfer dashboards to new Grafana instances
- Dual Redundancy: Backs up to two separate NAS devices (Synology DS418 and Proxmox OMV)
- API-Based: Uses Grafana API for programmatic backup (no filesystem access needed)
- Clean JSON Export: Saves dashboards without API wrapper metadata
Requirements
- Ansible 2.9 or higher
- Collection:
community.general(for archive module) - Grafana with API access enabled
- Grafana API token with appropriate permissions (stored in Ansible Vault)
- NAS mount points must be accessible and writable
- Network connectivity to Grafana server (typically port 3000)
Role Variables
Required Variables
| Variable | Required | Description |
|---|---|---|
vault_grafana_ansibleuser_api_token | Yes | Grafana API token (stored in Ansible Vault) |
Optional Variables
| Variable | Default | Description |
|---|---|---|
grafana_dashboards_backup_host | {{ hostvars['grafana']['ansible_host'] }}:3000 | Grafana host and port |
grafana_dashboards_backup_port | 3000 | Grafana web interface port |
grafana_dashboards_backup_validate_certs | true | Validate SSL certificates |
grafana_dashboards_backup_syno_mount_point | /mnt/synology-ds418/grafana/dashboards | Synology NAS backup destination |
grafana_dashboards_backup_prxmxomv_mount_point | /mnt/prxmx-omv/grafana/dashboards | Proxmox OMV NAS backup destination |
Variable Details
vault_grafana_ansibleuser_api_token
Grafana API token with permissions to read dashboards. Create in Grafana UI: Configuration → API Keys.
Required permissions:
- Read dashboards
- Read folders (to get dashboard list)
Example vault variable:
vault_grafana_ansibleuser_api_token: "glsa_1234567890abcdefghijklmnopqrstuvwxyz"
grafana_dashboards_backup_validate_certs
Set to false if using self-signed certificates.
Example:
grafana_dashboards_backup_validate_certs: false
Dependencies
This role has no dependencies on other Ansible roles, but requires:
- Grafana instance accessible via HTTPS
- NAS mounts configured (see
nas_mountornas_mount_systemdroles) - Grafana API token configured
Example Playbook
Basic Usage
---
- name: Backup Grafana Dashboards
hosts: localhost
become: true
roles:
- grafana_dashboards_backup
With Custom Grafana Host
---
- name: Backup Grafana Dashboards from Custom Host
hosts: localhost
become: true
vars:
grafana_dashboards_backup_host: "monitoring.example.com:3000"
grafana_dashboards_backup_validate_certs: false
roles:
- grafana_dashboards_backup
Scheduled Backup with Cron
---
- name: Schedule Daily Grafana Dashboards Backup
hosts: localhost
become: true
tasks:
- name: Create cron job for daily Grafana dashboards backup
ansible.builtin.cron:
name: "Daily Grafana Dashboards Backup"
minute: "0"
hour: "3"
job: "ansible-playbook /path/to/grafana_dashboards_backup.yml"
What This Role Does
- Ensures backup directories exist on both NAS mount points
- Retrieves dashboard list from Grafana API (
/api/search?type=dash-db) - Creates temporary directory for staging dashboard files
- Downloads each dashboard individually using dashboard UID (
/api/dashboards/uid/{uid}) - Extracts pure JSON (removes API wrapper metadata)
- Saves each dashboard as separate JSON file with sanitized filename
- Creates timestamped tar.gz archive of all JSON files
- Copies archive to both NAS devices
- Cleans up temporary files and local archive
- Removes old backups, keeping only the 5 most recent per NAS
Backup Format
Dashboards are saved as pure JSON files, one file per dashboard:
Directory Structure (inside archive)
grafana_dashboards_20260107T143022.tar.gz
├── abc123_System_Overview.json
├── def456_Application_Metrics.json
├── ghi789_Infrastructure_Dashboard.json
└── jkl012_Database_Performance.json
JSON File Naming
{dashboard_uid}_{dashboard_title}.json
Examples:
abc123_System_Overview.jsondef456_Application_Metrics.json
Special characters in titles are replaced with underscores for filesystem safety.
JSON Content Format
The dashboard JSON is pure Grafana dashboard format (without API wrapper):
{
"id": null,
"uid": "abc123",
"title": "System Overview",
"tags": ["system", "monitoring"],
"timezone": "browser",
"panels": [
{
"id": 1,
"type": "graph",
"title": "CPU Usage",
"targets": [...]
}
],
"templating": {...},
"annotations": {...},
"schemaVersion": 38
}
This format:
- Can be imported directly into Grafana UI (Dashboards → Import)
- Is compatible with Grafana provisioning
- Can be restored using
grafana_dashboards_restorerole - Is human-readable and diff-friendly for version control
Backup Content
The backup includes:
- All dashboards from all folders
- Panel configurations (visualizations, queries, thresholds)
- Template variables
- Annotations
- Dashboard settings (time range, refresh, tags)
- Panel layouts and positioning
The backup does NOT include:
- Dashboard permissions
- Dashboard versions/history
- Folder structure (only dashboard content)
- Datasource configurations (use
grafana_datasource_createrole) - Alert rules (use
grafana_alerts_backuprole)
Backup Retention
The role implements automatic retention management:
- Keeps: Last 5 backups per NAS
- Deletes: Backups older than the 5th most recent
- Per-NAS logic: Each NAS independently maintains 5 backups
This ensures you have:
- 5 backups on Synology DS418
- 5 backups on Proxmox OMV
- Total: Up to 10 backup copies across both devices
File Naming Convention
Backup archives are named using ISO 8601 basic short format:
grafana_dashboards_YYYYMMDDTHHMMSS.tar.gz
Examples:
grafana_dashboards_20260107T143022.tar.gzgrafana_dashboards_20260107T190530.tar.gz
API Wrapper Removal
Grafana API returns dashboards wrapped in metadata:
{
"meta": {
"type": "db",
"canSave": true,
"canEdit": true,
...
},
"dashboard": {
"id": 1,
"uid": "abc123",
"title": "My Dashboard",
...
}
}
The role extracts only the dashboard object for cleaner backups:
content: "{{ item.json.dashboard | to_nice_json }}"
This ensures:
- ✅ Backed up JSON is directly importable
- ✅ No API-specific metadata pollutes the backup
- ✅ Smaller file sizes
- ✅ Cleaner version control diffs
API Endpoints Used
1. Search Dashboards
GET /api/search?type=dash-db
Authorization: Bearer {api_token}
Returns list of all dashboards with:
- Dashboard UID
- Dashboard title
- Folder information
- Dashboard type
2. Get Dashboard by UID
GET /api/dashboards/uid/{uid}
Authorization: Bearer {api_token}
Returns complete dashboard JSON including:
- Panel configurations
- Template variables
- Annotations
- Dashboard settings
Restoration
To restore from a backup, use the companion grafana_dashboards_restore role or manually:
Via Grafana UI
- Extract the archive:
tar -xzf grafana_dashboards_20260107T143022.tar.gz - In Grafana: Dashboards → Import
- Upload or paste JSON content
- Configure datasource mappings if needed
- Click “Import”
Via Provisioning
# Extract the archive
tar -xzf grafana_dashboards_20260107T143022.tar.gz
# Place JSON files in provisioning directory
sudo cp *.json /etc/grafana/provisioning/dashboards/
# Restart Grafana
sudo systemctl restart grafana-server
Security Considerations
- API Token Protection: Token used in HTTP headers (HTTPS recommended)
- Vault Storage: API token must be stored in Ansible Vault
- Certificate Validation: Enabled by default, only disable for trusted networks
- File Permissions: Backup files created with mode 0644
- Sensitive Data: Dashboard queries may contain sensitive information
Tags
This role does not define any tags. Use playbook-level tags if needed:
- hosts: localhost
roles:
- grafana_dashboards_backup
tags:
- backup
- grafana
- monitoring
- dashboards
Notes
- The role uses Grafana’s stable REST API
- Each dashboard is downloaded individually for better error handling
- Dashboard titles with special characters are sanitized in filenames
- Temporary files are always cleaned up, even if the backup fails
- The role processes all dashboards regardless of folder
Troubleshooting
”Unauthorized” or 401 errors
Verify the API token:
- Check token is valid in Grafana UI
- Ensure token has read permissions for dashboards
- Confirm token hasn’t expired
Test manually:
curl -H "Authorization: Bearer YOUR_TOKEN" https://grafana:3000/api/search?type=dash-db
“Connection refused” errors
Verify:
- Grafana is running:
systemctl status grafana-server - Port 3000 is accessible:
nc -zv grafana-host 3000 - Firewall allows connections
”Permission denied” when writing to NAS
Ensure:
- NAS is mounted:
mount | grep synology - Backup directories exist and are writable
- User has write permissions
No dashboards backed up (but you have dashboards)
Check:
- API token permissions include dashboard access
- Dashboards are not in “General Alerting” or system folders
- Search API returns results:
curl -H "Authorization: Bearer TOKEN" https://grafana:3000/api/search?type=dash-db
SSL certificate verification fails
If using self-signed certificates:
grafana_dashboards_backup_validate_certs: false
Backup archive is very large
Dashboards with many panels create larger JSON files. This is normal. To reduce size:
- Remove unused dashboards
- Archive old dashboards manually
- Consider compressing with higher compression levels
Performance Considerations
- Download time depends on number of dashboards (typically 1-2 seconds per dashboard)
- Archive creation is fast (typically < 1 second)
- Network bandwidth to NAS may be the bottleneck
- API calls are sequential to avoid overwhelming Grafana
Typical performance:
- 10 dashboards: ~15-20 seconds
- 50 dashboards: ~1-2 minutes
- 100 dashboards: ~2-3 minutes
Grafana Version Compatibility
- Grafana 6.0+: Full support
- Grafana 7.0+: Full support
- Grafana 8.0+: Full support
- Grafana 9.0+: Full support with enhanced features
- Grafana 10.0+: Full support
The role uses stable API endpoints that have been consistent across versions.
Related Roles
- grafana_dashboards_restore: Restores dashboards from backups created by this role
- grafana_alerts_backup: Backs up Grafana alert rules
- grafana_install: Installs and configures Grafana server
- grafana_datasource_create: Configures datasources used by dashboards
Best Practices
- Schedule regular backups (daily or weekly depending on change frequency)
- Test restore procedures periodically to verify backup integrity
- Version control dashboard JSON for tracking changes over time
- Document datasource mappings for restoration to different environments
- Keep backups offsite (the dual NAS approach provides good redundancy)
License
MIT
Author
Created for homelab infrastructure management.