Grafana Dashboards Restore
This role restores Grafana dashboards from backup archives created by `grafana_dashboards_backup`.
Grafana Dashboards Restore Role
Overview
This role restores Grafana dashboards from backup archives created by grafana_dashboards_backup. It automatically identifies the latest backup, extracts dashboard JSON files, and imports them into Grafana using the API with overwrite capability. The role handles conflicts gracefully by updating existing dashboards.
Purpose
- Disaster Recovery: Restore dashboard configurations after data loss
- Migration: Transfer dashboards to new Grafana instances
- Environment Cloning: Replicate production dashboards in testing environments
- Version Rollback: Restore previous dashboard versions
- Automated Import: Batch import multiple dashboards simultaneously
- Conflict Resolution: Overwrites existing dashboards instead of failing
Requirements
- Ansible 2.9 or higher
- Grafana with API access enabled
- Grafana API token with appropriate permissions (stored in Ansible Vault)
- Dashboard backup archives created by
grafana_dashboards_backuprole - NAS mount point accessible with backup files
- 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_restore_backup_path | /mnt/synology-ds418/grafana/dashboards | Directory containing backup archives |
grafana_dashboards_restore_host | {{ hostvars['grafana']['ansible_host'] }}:3000 | Grafana host and port |
grafana_dashboards_restore_port | 3000 | Grafana HTTP port |
grafana_dashboards_restore_validate_certs | true | Validate SSL certificates |
Variable Details
vault_grafana_ansibleuser_api_token
Grafana API token with permissions to create/update dashboards.
Required permissions:
- Create/update dashboards
- Write to folders (where dashboards are created)
Example vault variable:
vault_grafana_ansibleuser_api_token: "glsa_1234567890abcdefghijklmnopqrstuvwxyz"
grafana_dashboards_restore_backup_path
Directory containing the backup tar.gz files. The role searches for files matching grafana_dashboards_*.tar.gz.
Example:
grafana_dashboards_restore_backup_path: /mnt/backup/grafana/dashboards
grafana_dashboards_restore_validate_certs
Set to false if using self-signed certificates.
Example:
grafana_dashboards_restore_validate_certs: false
Dependencies
This role has no dependencies on other Ansible roles, but requires:
- Grafana instance accessible via HTTPS
- Dashboard backups created by
grafana_dashboards_backuprole - NAS mount configured (if restoring from network storage)
Example Playbook
Basic Usage (Restore Latest Backup)
---
- name: Restore Grafana Dashboards
hosts: localhost
roles:
- grafana_dashboards_restore
Restore to Different Grafana Instance
---
- name: Restore Dashboards to New Grafana Server
hosts: localhost
vars:
grafana_dashboards_restore_host: "new-grafana.example.com:3000"
grafana_dashboards_restore_validate_certs: true
roles:
- grafana_dashboards_restore
Restore with Custom Backup Location
---
- name: Restore Dashboards from Custom Backup
hosts: localhost
vars:
grafana_dashboards_restore_backup_path: /mnt/backup2/grafana/dashboards
roles:
- grafana_dashboards_restore
What This Role Does
- Finds latest backup archive matching pattern
grafana_dashboards_*.tar.gz - Sorts by modification time and selects the most recent
- Fails gracefully if no backups are found
- Creates temporary directory for extraction
- Extracts backup archive to temporary location
- Finds all JSON files in extracted backup
- Reads each dashboard JSON file
- Imports dashboards via Grafana API with overwrite enabled
- Cleans up temporary files
Backup File Selection
The role automatically selects the most recent backup using these criteria:
- Searches for files matching pattern:
grafana_dashboards_*.tar.gz - Sorts by modification time (mtime)
- Uses the newest file
Example backup files (newest first):
grafana_dashboards_20260107T190530.tar.gz <- This will be used
grafana_dashboards_20260107T143022.tar.gz
grafana_dashboards_20260106T020000.tar.gz
Import Process
For each dashboard JSON file:
- Reads the JSON content from file
- Decodes base64 encoding
- Parses JSON structure
- Sets id to None (allows Grafana to assign ID)
- Sends POST request to
/api/dashboards/dbwith:dashboard: The dashboard JSONoverwrite:true(updates existing dashboards)message: Restore metadata for version history
Overwrite Behavior
The role uses overwrite: true which means:
✅ Existing dashboards with same UID: Will be updated with backup content ✅ New dashboards: Will be created ✅ Dashboard versions: New version created with restore message ✅ No conflicts: Safe to run multiple times
Version History Message:
Restored from backup grafana_dashboards_20260107T190530.tar.gz
This appears in Grafana’s dashboard version history for auditing.
Dashboard ID Handling
The role sets id: None when importing:
dashboard: "{{ (item.content | b64decode | from_json) | combine({'id': None}) }}"
Why this matters:
- Dashboard IDs are database-specific
- Setting
id: Nonetells Grafana to assign appropriate ID - Allows same backup to be restored to multiple Grafana instances
- Prevents ID conflicts
What Gets Restored
The restoration includes:
- All dashboards from the backup
- Panel configurations (visualizations, queries, thresholds)
- Template variables
- Annotations
- Dashboard settings (time range, refresh, tags)
- Panel layouts and positioning
- Dashboard UIDs (preserved for consistency)
The restoration does NOT restore:
- Dashboard permissions (uses defaults)
- Folder structure (dashboards go to current user’s default folder or as specified in JSON)
- Dashboard stars/favorites
- Historical versions (creates new version)
Datasource Mapping
Dashboards reference datasources by UID. If datasource UIDs don’t match between source and target Grafana:
Option 1: Update datasources before restore
# Ensure target Grafana has datasources with matching UIDs
- name: Create datasources
ansible.builtin.include_role:
name: grafana_datasource_create
Option 2: Manual mapping in Grafana UI After import, Grafana UI prompts to map datasources if UIDs don’t match.
Option 3: Pre-process JSON files Replace old datasource UIDs with new ones before import (advanced).
API Endpoint Used
Import Dashboard
POST /api/dashboards/db
Authorization: Bearer {api_token}
Content-Type: application/json
Body:
{
"dashboard": {dashboard_json},
"overwrite": true,
"message": "Restored from backup ..."
}
Response (200 OK):
{
"id": 1,
"uid": "abc123",
"url": "/d/abc123/dashboard-title",
"status": "success",
"version": 5
}
Post-Restoration Verification
After restoration, verify in Grafana UI:
- Check dashboards: Browse to Dashboards
- Open each dashboard: Verify panels load correctly
- Check datasources: Ensure queries work
- Review variables: Test template variable dropdowns
- Check version history: Confirm restore message appears
Error Handling
Dashboard Import Failures
If a dashboard fails to import:
- Role continues with remaining dashboards
- Failed dashboard details logged in Ansible output
- Check Grafana logs:
/var/log/grafana/grafana.log
Common causes:
- Invalid JSON format
- Missing datasource UIDs
- Insufficient permissions
- Grafana version incompatibility
Security Considerations
- API Token Protection: Token used in HTTP headers (HTTPS recommended)
- Vault Storage: API token must be in Ansible Vault
- Certificate Validation: Enabled by default, only disable for trusted networks
- Overwrite Risk: Existing dashboards are overwritten without confirmation
- Backup Before Restore: Consider backing up current dashboards before restoration
Tags
This role does not define any tags. Use playbook-level tags if needed:
- hosts: localhost
roles:
- grafana_dashboards_restore
tags:
- restore
- grafana
- disaster-recovery
- dashboards
Notes
- The role uses Grafana’s stable dashboard import API
- Dashboards are imported individually for better error handling
- Dashboard IDs are reset to allow Grafana to assign them
- Temporary files are always cleaned up, even if restoration fails
- The role is idempotent - safe to run multiple times
Troubleshooting
”No backup files found”
Verify:
- NAS is mounted:
mount | grep synology - Backup directory exists:
ls -l /mnt/synology-ds418/grafana/dashboards/ - Backup files exist:
ls -l /mnt/synology-ds418/grafana/dashboards/grafana_dashboards_*.tar.gz
”Unauthorized” or 401 errors
Verify API token:
- Check token is valid in Grafana UI
- Ensure token has dashboard write permissions
- Confirm token hasn’t expired
Test manually:
curl -X POST -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
-d '{"dashboard":{"title":"Test"},"overwrite":true}' \
https://grafana:3000/api/dashboards/db
Dashboards imported but panels show “No Data”
Check:
- Datasource UIDs match between source and target
- Datasources are configured and working
- Queries are valid for target Grafana version
Dashboard import returns “Name already exists”
This shouldn’t happen with overwrite: true. If it does:
- Check the dashboard UID in JSON matches existing dashboard
- Try deleting the existing dashboard manually
- Check Grafana logs for details
SSL certificate verification fails
If using self-signed certificates:
grafana_dashboards_restore_validate_certs: false
Datasource UID warnings in Grafana UI
After import, Grafana may prompt to map datasources:
- Click on the datasource warning
- Select the correct datasource from dropdown
- Click “Save”
Prevent this: Ensure datasource UIDs match before import.
Performance Considerations
- Import time depends on number of dashboards (typically 1-2 seconds per dashboard)
- Large dashboards (many panels) take longer to import
- API rate limiting may apply for very large restores
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
- Grafana 10.0+: Full support
Note: Dashboards created in newer Grafana versions may not work in older versions due to schema changes.
Migration Best Practices
When migrating dashboards between Grafana instances:
- Backup current state before restoration
- Match datasource UIDs if possible
- Test in staging before production
- Verify panel queries work in target environment
- Check Grafana versions are compatible
- Review permissions after import
Related Roles
- grafana_dashboards_backup: Creates the backup files this role restores
- grafana_alerts_restore: Restores Grafana alert rules
- grafana_datasource_create: Configures datasources for dashboard queries
- grafana_install: Installs and configures Grafana server
Alternative: Manual Restoration
If you need more control:
# Extract the archive
tar -xzf /mnt/synology-ds418/grafana/dashboards/grafana_dashboards_20260107T143022.tar.gz
# Import each dashboard manually via Grafana UI
# Dashboards → Import → Upload JSON file
# Or paste JSON content directly
# Or use curl
for json in *.json; do
curl -X POST -H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d @"$json" \
https://grafana:3000/api/dashboards/db
done
License
MIT
Author
Created for homelab infrastructure management.