# Kibana Object Manager - Real-World Examples
Practical examples and recipes for common use cases.
## Table of Contents
- [For Kibana Admins](#for-kibana-admins)
- [For Developers](#for-developers)
- [For DevOps Engineers](#for-devops-engineers)
- [Advanced Scenarios](#advanced-scenarios)
---
## For Kibana Admins
### Example 1: Weekly Dashboard Backup
**Scenario:** Automatically back up production dashboards every week.
**Setup:**
Create a backup script `backup-dashboards.sh`:
```bash
#!/bin/bash
set -e
# Configuration
BACKUP_DIR="$HOME/kibana-backups"
PROJECT_NAME="production-dashboards"
DATE=$(date +%Y-%m-%d)
# Load production credentials
export KIBANA_URL="https://prod-kibana.example.com"
export KIBANA_APIKEY="your_prod_api_key"
# Create dated backup directory
BACKUP_PATH="$BACKUP_DIR/$PROJECT_NAME-$DATE"
mkdir -p "$BACKUP_PATH"
# Pull from Kibana (all spaces in spaces.yml)
echo "Backing up dashboards from $KIBANA_URL..."
kibob pull "$BACKUP_PATH"
# Create archive
cd "$BACKUP_DIR"
tar -czf "$PROJECT_NAME-$DATE.tar.gz" "$PROJECT_NAME-$DATE"
echo "Backup saved: $PROJECT_NAME-$DATE.tar.gz"
# Keep only last 30 days
find "$BACKUP_DIR" -name "$PROJECT_NAME-*.tar.gz" -mtime +30 -delete
```
Add to crontab:
```bash
# Run every Sunday at 2 AM
0 2 * * 0 /path/to/backup-dashboards.sh >> /var/log/kibana-backup.log 2>&1
```
---
### Example 2: Restore Deleted Dashboard
**Scenario:** A dashboard was accidentally deleted in production. Restore it from Git.
```bash
# 1. Clone your dashboard repository
git clone https://github.com/yourorg/kibana-dashboards.git
cd kibana-dashboards
# 2. Find the dashboard in your objects
# With multi-space structure: {space_id}/objects/dashboard/
ls -la default/objects/dashboard/
# Let's say the deleted dashboard is: sales-overview.json
# 3. Set production credentials
export KIBANA_URL=https://prod-kibana.example.com
export KIBANA_APIKEY=prod_api_key
# 4. Verify connection
kibob auth
# 5. Push the dashboard (it will be recreated in the default space)
kibob push . --managed true
# 6. Verify restoration
kibob pull ./verify-restore
diff -r default/objects/ verify-restore/default/objects/
```
---
### Example 3: Clone Dashboards to New Space
**Scenario:** Copy all dashboards from default space to a new team space.
```bash
# 1. Set up your project with both spaces
export KIBANA_URL=http://localhost:5601
export KIBANA_USERNAME=elastic
export KIBANA_PASSWORD=changeme
# 2. Add both spaces to manifest
cd my-dashboards
kibob add spaces .
# This creates spaces.yml with all available spaces
# 3. Edit spaces.yml to include only the spaces you want
vim spaces.yml
# Keep 'default' and 'team-alpha' spaces
# 4. Pull from both spaces
kibob pull .
# Creates:
# default/objects/dashboard/...
# team-alpha/objects/dashboard/...
# 5. Copy dashboards from default to team-alpha
cp -r default/objects/dashboard/* team-alpha/objects/dashboard/
# 6. Update manifest for team-alpha space
# Add the new dashboards to team-alpha/manifest/saved_objects.json
# 7. Push to team-alpha space
kibob push . --managed false # Unmanaged so team can customize
echo "Dashboards cloned to team-alpha space"
```
---
### Example 4: Migrate Dashboards Between Clusters
**Scenario:** Move dashboards from old Kibana cluster to new cluster.
```bash
# 1. Export from old cluster
export KIBANA_URL=https://old-kibana.example.com
export KIBANA_USERNAME=admin
export KIBANA_PASSWORD=old_password
kibob pull ./migration-dashboards
# 2. Create archive for audit trail
tar -czf migration-$(date +%Y%m%d).tar.gz migration-dashboards/
# 3. Import to new cluster
export KIBANA_URL=https://new-kibana.example.com
export KIBANA_APIKEY=new_cluster_api_key
# Test connection
kibob auth
# Import as unmanaged for testing
kibob push ./migration-dashboards --managed false
# After verification, push as managed
kibob push ./migration-dashboards --managed true
```
---
## For Developers
### Example 5: Version Control Dashboards with Application Code
**Scenario:** Store observability dashboards in your application's Git repository.
**Project Structure (Multi-Space):**
```
my-application/
├── src/
│ └── ... (application code)
├── tests/
│ └── ...
├── dashboards/ # Kibana dashboards (multi-space)
│ ├── .env.example
│ ├── spaces.yml # Managed spaces
│ ├── default/ # Default space
│ │ ├── space.json
│ │ ├── manifest/
│ │ │ └── saved_objects.json
│ │ └── objects/
│ │ ├── dashboard/
│ │ │ ├── app-overview.json
│ │ │ └── error-tracking.json
│ │ └── index-pattern/
│ │ └── app-logs-*.json
│ └── monitoring/ # Monitoring space (optional)
│ ├── space.json
│ ├── manifest/
│ │ └── saved_objects.json
│ └── objects/
│ └── dashboard/
│ └── system-health.json
└── README.md
```
**Workflow:**
```bash
# Developer setup
cd my-application/dashboards
cp .env.example .env
# Edit .env with your dev Kibana credentials
# Deploy dashboards to dev Kibana (all spaces in spaces.yml)
kibob push . --managed false
# Make changes to dashboard in Kibana
# Pull changes back
kibob pull .
# See what changed across all spaces
git diff
# Commit with application code
git add .
git commit -m "feat: Add error rate tracking to dashboard"
git push origin feature/error-tracking
```
**CI/CD Integration (.github/workflows/deploy.yml):**
```yaml
name: Deploy Application
on:
push:
branches: [main]
jobs:
deploy-dashboards:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install kibob
run: cargo install kibana-object-manager
- name: Deploy Dashboards (All Spaces)
env:
KIBANA_URL: ${{ secrets.KIBANA_URL }}
KIBANA_APIKEY: ${{ secrets.KIBANA_APIKEY }}
run: |
cd dashboards
kibob auth
kibob push . --managed true
deploy-application:
needs: deploy-dashboards
runs-on: ubuntu-latest
steps:
- name: Deploy app
run: |
# ... deploy application
```
---
### Example 6: Feature Branch Dashboards
**Scenario:** Test dashboard changes in a feature branch environment.
```bash
# Create feature branch
git checkout -b feature/new-metrics-dashboard
# Create new dashboard in Kibana (in default space)
# Add it to manifest
kibob add objects ./dashboards --objects "dashboard=new-metrics-abc123"
# This adds to default/manifest/saved_objects.json
# Pull the new dashboard
kibob pull ./dashboards
# Commit changes
git add dashboards/default/
git commit -m "Add new metrics dashboard"
git push origin feature/new-metrics-dashboard
# Deploy to feature environment
export KIBANA_URL=https://feature-kibana.dev.example.com
export KIBANA_APIKEY=feature_env_key
kibob push ./dashboards
# After code review and merge
git checkout main
git merge feature/new-metrics-dashboard
# Deploy to production
export KIBANA_URL=https://prod-kibana.example.com
export KIBANA_APIKEY=prod_key
kibob push ./dashboards --managed true
```
---
### Example 7: Local Development with Docker Compose
**Scenario:** Run local Kibana for dashboard development.
**docker-compose.yml:**
```yaml
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
environment:
- discovery.type=single-node
- xpack.security.enabled=false
ports:
- "9200:9200"
kibana:
image: docker.elastic.co/kibana/kibana:8.11.0
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
ports:
- "5601:5601"
depends_on:
- elasticsearch
```
**Development workflow:**
```bash
# Start local stack
docker-compose up -d
# Wait for Kibana to be ready
sleep 5
done
# Deploy dashboards (all spaces in spaces.yml)
export KIBANA_URL=http://localhost:5601
export KIBANA_USERNAME=elastic
export KIBANA_PASSWORD=changeme
kibob push ./dashboards --managed false
# Develop and iterate
# ... make changes in Kibana UI ...
kibob pull ./dashboards
git diff
# Clean up
docker-compose down -v
```
---
## For DevOps Engineers
### Example 8: Multi-Environment CI/CD Pipeline
**Scenario:** Automated dashboard deployment across dev → staging → prod.
**Jenkins Pipeline:**
```groovy
pipeline {
agent any
environment {
DASHBOARDS_DIR = './dashboards'
}
stages {
stage('Install kibob') {
steps {
sh 'cargo install kibana-object-manager'
}
}
stage('Deploy to Dev') {
environment {
KIBANA_URL = credentials('kibana-dev-url')
KIBANA_APIKEY = credentials('kibana-dev-apikey')
}
steps {
sh '''
cd $DASHBOARDS_DIR
kibob auth
# Deploys all spaces defined in spaces.yml
kibob push . --managed true
'''
}
}
stage('Test Dev Deployment') {
environment {
KIBANA_URL = credentials('kibana-dev-url')
KIBANA_APIKEY = credentials('kibana-dev-apikey')
}
steps {
sh '''
cd $DASHBOARDS_DIR
kibob pull ./verify
# Compare all spaces
for space in default monitoring; do
diff -r $space/objects/ verify/$space/objects/
done
'''
}
}
stage('Deploy to Staging') {
when {
branch 'main'
}
environment {
KIBANA_URL = credentials('kibana-staging-url')
KIBANA_APIKEY = credentials('kibana-staging-apikey')
}
steps {
sh '''
cd $DASHBOARDS_DIR
kibob auth
kibob push . --managed true
'''
}
}
stage('Approve Production') {
when {
branch 'main'
}
steps {
input message: 'Deploy to Production?', ok: 'Deploy'
}
}
stage('Deploy to Production') {
when {
branch 'main'
}
environment {
KIBANA_URL = credentials('kibana-prod-url')
KIBANA_APIKEY = credentials('kibana-prod-apikey')
}
steps {
sh '''
cd $DASHBOARDS_DIR
kibob auth
kibob push . --managed true
'''
}
}
}
post {
failure {
slackSend color: 'danger',
message: "Dashboard deployment failed: ${env.JOB_NAME} ${env.BUILD_NUMBER}"
}
success {
slackSend color: 'good',
message: "Dashboards deployed successfully: ${env.JOB_NAME} ${env.BUILD_NUMBER}"
}
}
}
```
---
### Example 9: GitOps Dashboard Management
**Scenario:** Use ArgoCD/Flux for GitOps-style dashboard deployment.
**Repository Structure:**
```
kibana-gitops/
├── base/
│ ├── spaces.yml # Managed spaces
│ ├── default/
│ │ ├── space.json
│ │ ├── manifest/
│ │ │ └── saved_objects.json
│ │ └── objects/
│ │ └── ...
│ └── kustomization.yaml
├── overlays/
│ ├── dev/
│ │ ├── .env
│ │ └── kustomization.yaml
│ ├── staging/
│ │ ├── .env
│ │ └── kustomization.yaml
│ └── prod/
│ ├── .env
│ └── kustomization.yaml
└── README.md
```
**Kubernetes CronJob (deploy-dashboards.yaml):**
```yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: kibana-dashboard-sync
namespace: observability
spec:
schedule: "*/30 * * * *" # Every 30 minutes
jobTemplate:
spec:
template:
spec:
serviceAccountName: kibana-deployer
containers:
- name: kibob
image: rust:1.75
command:
- /bin/bash
- -c
- |
cargo install kibana-object-manager
git clone https://github.com/yourorg/kibana-gitops.git
cd kibana-gitops/base
# Syncs all spaces in spaces.yml
kibob push . --managed true
env:
- name: KIBANA_URL
valueFrom:
secretKeyRef:
name: kibana-credentials
key: url
- name: KIBANA_APIKEY
valueFrom:
secretKeyRef:
name: kibana-credentials
key: apikey
restartPolicy: OnFailure
```
---
### Example 10: Terraform Integration
**Scenario:** Manage Kibana dashboards with Terraform.
**main.tf:**
```hcl
resource "null_resource" "kibana_dashboards" {
triggers = {
# Redeploy when spaces manifest changes
spaces_hash = filemd5("${path.module}/dashboards/spaces.yml")
# Or when any manifest changes
manifests_hash = md5(join("", [
for f in fileset("${path.module}/dashboards", "*/manifest/saved_objects.json"):
filemd5("${path.module}/dashboards/${f}")
]))
}
provisioner "local-exec" {
command = <<-EOT
export KIBANA_URL="${var.kibana_url}"
export KIBANA_APIKEY="${var.kibana_apikey}"
kibob auth
kibob push ${path.module}/dashboards --managed true
EOT
}
}
variable "kibana_url" {
description = "Kibana URL"
type = string
}
variable "kibana_apikey" {
description = "Kibana API Key"
type = string
sensitive = true
}
output "dashboard_sync" {
value = "Dashboards synchronized across all spaces"
depends_on = [null_resource.kibana_dashboards]
}
```
**Usage:**
```bash
terraform init
terraform plan -var="kibana_url=https://kibana.example.com" \
-var="kibana_apikey=$KIBANA_APIKEY"
terraform apply
```
---
## Advanced Scenarios
### Example 11: Selective Space Management
**Scenario:** Manage only production spaces, exclude development experiments.
```bash
# Start with all objects
kibob init export.ndjson ./dashboards
# Discover all spaces
kibob add spaces ./dashboards
# Edit spaces.yml to keep only production spaces
vim dashboards/spaces.yml
# Remove experimental spaces, keep only:
# - default
# - monitoring
# - security
# Pull will now only fetch objects from these spaces
kibob pull ./dashboards
# Directory structure:
# dashboards/
# ├── spaces.yml (only lists: default, monitoring, security)
# ├── default/...
# ├── monitoring/...
# └── security/...
# Push only manages the spaces in spaces.yml
kibob push ./dashboards --managed true
```
---
### Example 12: Per-Space Dashboard Filtering
**Scenario:** Different teams manage different spaces independently.
```bash
# Team A manages only their space
cat > team-a-dashboards/spaces.yml << EOF
spaces:
- id: team-a
name: Team A
EOF
kibob pull ./team-a-dashboards
# Only pulls objects from team-a space
# Team B manages their space
cat > team-b-dashboards/spaces.yml << EOF
spaces:
- id: team-b
name: Team B
EOF
kibob pull ./team-b-dashboards
# Only pulls objects from team-b space
# Platform team manages all spaces
kibob add spaces ./platform-dashboards
# Creates spaces.yml with all spaces
kibob pull ./platform-dashboards
# Pulls from all spaces
```
---
### Example 13: Automated Dashboard Testing
**Scenario:** Validate dashboards before deployment.
**validate-dashboards.sh:**
```bash
#!/bin/bash
set -e
DASHBOARDS_DIR="./dashboards"
echo "Validating dashboard structure..."
# Check spaces manifest exists
if [ ! -f "$DASHBOARDS_DIR/spaces.yml" ]; then
echo "Error: spaces.yml not found"
exit 1
fi
# Validate spaces.yml
if ! yq eval '.' "$DASHBOARDS_DIR/spaces.yml" > /dev/null; then
echo "Error: Invalid spaces.yml"
exit 1
fi
# Check each space's structure
for space_dir in "$DASHBOARDS_DIR"/*/; do
space_id=$(basename "$space_dir")
# Skip non-directory files
echo "Validating space: $space_id"
# Check manifest exists
manifest="$space_dir/manifest/saved_objects.json"
if [ ! -f "$manifest" ]; then
echo "Error: Manifest not found for $space_id"
exit 1
fi
# Validate manifest JSON
if ! jq empty "$manifest"; then
echo "Error: Invalid manifest JSON for $space_id"
exit 1
fi
# Check all referenced objects exist
missing_count=0
while IFS= read -r object; do
type=$(echo "$object" | jq -r '.type')
id=$(echo "$object" | jq -r '.id')
file="$space_dir/objects/$type/$id.json"
if [ ! -f "$file" ]; then
echo "Error: Missing object file: $file"
((missing_count++))
fi
done < <(jq -c '.objects[]' "$manifest")
if [ $missing_count -gt 0 ]; then
echo "Validation failed for $space_id: $missing_count missing objects"
exit 1
fi
echo "✓ Space $space_id validated"
done
echo "✓ Dashboard validation passed"
# Test deployment to dev environment
echo "Testing deployment to dev..."
export KIBANA_URL="${DEV_KIBANA_URL}"
export KIBANA_APIKEY="${DEV_KIBANA_APIKEY}"
kibob auth
kibob push "$DASHBOARDS_DIR" --managed false
echo "✓ Dev deployment successful"
```
**GitHub Actions workflow:**
```yaml
name: Validate Dashboards
on:
pull_request:
paths:
- 'dashboards/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: |
cargo install kibana-object-manager
sudo apt-get install -y jq yq
- name: Validate dashboards
env:
DEV_KIBANA_URL: ${{ secrets.DEV_KIBANA_URL }}
DEV_KIBANA_APIKEY: ${{ secrets.DEV_KIBANA_APIKEY }}
run: ./validate-dashboards.sh
```
---
### Example 14: Dashboard as Code Review Process
**Scenario:** Require code review for dashboard changes.
**.github/CODEOWNERS:**
```
# Dashboard changes require review from platform team
/dashboards/ @yourorg/platform-team
# Space-specific owners
/dashboards/security/ @yourorg/security-team
/dashboards/monitoring/ @yourorg/sre-team
/dashboards/team-a/ @yourorg/team-a
```
**Review checklist template (.github/pull_request_template.md):**
```markdown
## Dashboard Changes Checklist
- [ ] All dashboard titles follow naming convention
- [ ] No sensitive data in filter defaults
- [ ] Time ranges are appropriate
- [ ] Visualizations have descriptions
- [ ] Index patterns are documented
- [ ] Changes tested in dev environment
- [ ] Screenshots attached showing changes
- [ ] spaces.yml updated if new spaces added
## Affected Spaces
- [ ] default
- [ ] monitoring
- [ ] security
- [ ] Other: ___________
## Deployment Plan
- [ ] Deploy to dev
- [ ] Deploy to staging
- [ ] Deploy to production
## Rollback Plan
Git commit to rollback to: `________`
```
---
### Example 15: Disaster Recovery Drill
**Scenario:** Practice restoring from backup to validate recovery procedures.
```bash
#!/bin/bash
# disaster-recovery-drill.sh
set -e
echo "=== Kibana Dashboard Disaster Recovery Drill ==="
# 1. Document current state
export KIBANA_URL=https://prod-kibana.example.com
export KIBANA_APIKEY=prod_key
echo "Step 1: Backing up current state..."
mkdir -p ./dr-drill/before
kibob pull ./dr-drill/before
# Calculate checksums for all spaces
BEFORE_CHECKSUM=$(find ./dr-drill/before -type f -name "*.json" -exec md5sum {} \; | sort | md5sum)
echo "Before checksum: $BEFORE_CHECKSUM"
# 2. Simulate disaster (delete a dashboard)
echo "Step 2: Simulating disaster (deleting dashboard)..."
# (Manual step - delete a dashboard in Kibana UI)
read -p "Delete a dashboard in Kibana UI, then press Enter..."
# 3. Verify damage
echo "Step 3: Verifying damage..."
mkdir -p ./dr-drill/damaged
kibob pull ./dr-drill/damaged
DAMAGED_CHECKSUM=$(find ./dr-drill/damaged -type f -name "*.json" -exec md5sum {} \; | sort | md5sum)
echo "Damaged checksum: $DAMAGED_CHECKSUM"
if [ "$BEFORE_CHECKSUM" == "$DAMAGED_CHECKSUM" ]; then
echo "Error: No damage detected. Delete a dashboard and try again."
exit 1
fi
# 4. Restore from Git
echo "Step 4: Restoring from Git..."
git clone https://github.com/yourorg/kibana-dashboards.git ./dr-drill/restore
cd ./dr-drill/restore
kibob push . --managed true
# 5. Verify restoration
echo "Step 5: Verifying restoration..."
cd ../..
mkdir -p ./dr-drill/after
kibob pull ./dr-drill/after
AFTER_CHECKSUM=$(find ./dr-drill/after -type f -name "*.json" -exec md5sum {} \; | sort | md5sum)
echo "After checksum: $AFTER_CHECKSUM"
if [ "$BEFORE_CHECKSUM" == "$AFTER_CHECKSUM" ]; then
echo "✓ Disaster recovery successful!"
echo "Recovery time: $SECONDS seconds"
else
echo "✗ Recovery verification failed"
exit 1
fi
# 6. Cleanup
echo "Step 6: Cleaning up drill artifacts..."
rm -rf ./dr-drill
echo "=== Drill Complete ==="
```
---
## Tips and Tricks
### Tip 1: Use Shell Aliases for Common Operations
```bash
# Add to ~/.bashrc or ~/.zshrc
alias kdev='export KIBANA_URL=http://localhost:5601 KIBANA_USERNAME=elastic KIBANA_PASSWORD=changeme'
alias kprod='export KIBANA_URL=https://prod.example.com KIBANA_APIKEY=$(pass kibana/prod)'
alias kpull='kibob pull .'
alias kpush='kibob push . --managed true'
alias kdiff='kibob pull . && git diff'
```
### Tip 2: Pre-commit Hook for Validation
```bash
# .git/hooks/pre-commit
#!/bin/bash
# Validate spaces.yml
if [ -f "dashboards/spaces.yml" ]; then
yq eval '.' dashboards/spaces.yml > /dev/null || exit 1
fi
# Validate all space manifests
for manifest in dashboards/*/manifest/saved_objects.json; do
jq empty "$manifest" || exit 1
done
echo "✓ Dashboard validation passed"
fi
```
### Tip 3: Monitor Dashboard Drift
```bash
#!/bin/bash
# check-dashboard-drift.sh
# Run daily to detect unauthorized changes
kibob pull ./current
if ! diff -r ./dashboards ./current > /dev/null; then
echo "WARNING: Dashboard drift detected!"
# Show which spaces have drifted
for space in dashboards/*/; do
space_id=$(basename "$space")
if ! diff -r "./dashboards/$space_id" "./current/$space_id" > /dev/null 2>&1; then
echo " - Space '$space_id' has drifted"
fi
done
```
### Tip 4: Working with Specific Spaces
```bash
# Pull only a specific space by filtering spaces.yml
cat > my-project/spaces.yml << EOF
spaces:
- id: default
name: Default
EOF
kibob pull my-project # Only pulls 'default' space
# Or use --space flag (if implemented) to filter during pull
# kibob pull . --space default
```
---
Need more help? Check out:
- [User Guide](USER_GUIDE.md) - Complete command reference
- [Architecture](ARCHITECTURE.md) - How kibob works internally
- [Contributing](../CONTRIBUTING.md) - Help improve kibob