Автоматизация выделения дашбордов с помощью CI/CD
Ручное управление дашбордами Grafana может быть неэффективным и подверженным ошибкам. С Grafana Foundation SDK вы можете определять дашборды с помощью строго типизированного кода, фиксировать их в системах контроля версий и автоматически развёртывать с помощью GitHub Actions.
Зачем автоматизировать?
Автоматизация развёртывания дашбордов Grafana устраняет необходимость в ручном создании и обновлении дашбордов, обеспечивая их согласованность между средами.
Определяя дашборды как код и управляя ими через CI/CD, например GitHub Actions, вы получаете полный контроль версий, что позволяет легко отслеживать изменения со временем и при необходимости откатываться. Это также предотвращает дублирование, поскольку рабочий процесс разумно проверяет, существует ли дашборд, прежде чем решить, создавать его или обновлять.
Благодаря этому полностью автоматизированному конвейеру CI/CD вы можете сосредоточиться на улучшении своих дашбордов вместо ручной загрузки JSON-файлов в Grafana.
Полный исходный код примера можно найти в репозитории Introduction to the Foundation SDK на GitHub.
Обзор
В этом руководстве показано, как:
- Сгенерировать дашборд Grafana как код и отформатировать его для развёртывания в стиле Kubernetes
- Использовать GitHub Actions для развёртывания, проверки и обновления дашборда
В итоге вы сможете выделять свой дашборд как код, и каждое изменение вашего дашборда будет автоматически создаваться или обновляться в вашем экземпляре Grafana без ручного вмешательства.
1. Генерация JSON дашборда
Прежде чем развёртывать дашборд, определите его как код с помощью Grafana Foundation SDK.
Поскольку Grafana предоставляет API, совместимый с ресурсами Kubernetes, вам нужно внести некоторые изменения в код, чтобы вывести JSON дашборда в подходящем формате.
Этот скрипт:
- Генерирует JSON-файл дашборда Grafana
- Оборачивает его в формат API в стиле Kubernetes (
apiVersion,kind,metadata,spec) - Сохраняет его как
dashboard.jsonдля развёртывания
package main
import (
"encoding/json"
"log"
"os"
"github.com/grafana/grafana-foundation-sdk/go/cog"
"github.com/grafana/grafana-foundation-sdk/go/common"
"github.com/grafana/grafana-foundation-sdk/go/dashboard"
)
type DashboardWrapper struct {
APIVersion string `json:"apiVersion"`
Kind string `json:"kind"`
Metadata Metadata `json:"metadata"`
Spec dashboard.Dashboard `json:"spec"`
}
type Metadata struct {
Name string `json:"name"`
}
func main() {
builder := dashboard.NewDashboardBuilder("My Dashboard").
Uid("my-dashboard").
Tags([]string{"generated", "foundation-sdk", "go"}).
Refresh("5m").
Time("now-1h", "now").
Timezone(common.TimeZoneBrowser).
WithRow(dashboard.NewRowBuilder("Overview"))
dashboard, err := builder.Build()
if err != nil {
log.Fatalf("failed to build dashboard: %v", err)
}
dashboardWrapper := DashboardWrapper{
APIVersion: "dashboard.grafana.app/v1",
Kind: "Dashboard",
Metadata: Metadata{
Name: *dashboard.Uid,
},
Spec: dashboard,
}
dashboardJson, err := json.MarshalIndent(dashboardWrapper, "", " ")
if err != nil {
log.Fatalf("failed to marshal dashboard: %v", err)
}
err = os.WriteFile("dashboard.json", dashboardJson, 0644)
if err != nil {
log.Fatalf("failed to write dashboard to file: %v", err)
}
log.Printf("Dashboard JSON:\n%s", dashboardJson)
}
import { DashboardBuilder, RowBuilder } from '@grafana/grafana-foundation-sdk/dashboard';
import * as fs from 'fs';
// Generate the dashboard JSON
const dashboard = new DashboardBuilder('My Dashboard')
.uid('my-dashboard')
.tags(['generated', 'foundation-sdk', 'typescript'])
.refresh('5m')
.time({ from: 'now-1h', to: 'now' })
.timezone('browser')
.withRow(new RowBuilder('Overview'))
.build();
// Convert to Kubernetes-style format
const dashboardWrapper = {
apiVersion: "dashboard.grafana.app/v1",
kind: "Dashboard",
metadata: {
name: dashboard.uid!
},
spec: dashboard
};
// Save the formatted JSON to a file
const dashboardJSON = JSON.stringify(dashboardWrapper, null, 2);
fs.writeFileSync('dashboard.json', dashboardJSON, 'utf8');
console.log(`Dashboard JSON:\n${}`);
2. Автоматизация развёртывания с помощью GitHub Actions
Далее настройте GitHub Actions для автоматизации развёртывания дашборда Grafana с помощью Foundation SDK и
инструмента командной строки gcx, чтобы:
- Извлечь имя дашборда из
dashboard.json - Проверить, существует ли дашборд в вашем экземпляре Grafana
- Обновить его, если он существует, или создать, если его нет
Note
Следующая конфигурация GitHub Action предполагает, что вы используете генератор дашбордов на Go. Если вы используете один из других языков, поддерживаемых Foundation SDK, измените шаг Generate Dashboard JSON соответствующим образом.
Рабочий процесс развёртывания .github/workflows/deploy-dashboard.yml выглядит так:
name: Deploy Grafana Dashboard
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.24.6
- name: Verify Go version
run: go version
- name: Download and Extract gcx
run: |
curl -L -o gcx-x86_64.tar.gz "https://github.com/grafana/gcx/releases/download/${{ vars.GCX_VERSION }}/gcx_Linux_x86_64.tar.gz"
tar -xzf gcx-x86_64.tar.gz
chmod +x gcx
sudo mv gcx /usr/local/bin/gcx
- name: Generate Dashboard JSON
working-directory: ./github-actions-example
run: go run main.go
- name: Deploy Dashboard with gcx
env:
GRAFANA_SERVER: ${{ vars.GRAFANA_SERVER }}
GRAFANA_STACK_ID: ${{ vars.GRAFANA_STACK_ID }}
GRAFANA_TOKEN: ${{ secrets.GRAFANA_TOKEN }}
run: |
if [ -f dashboard.json ]; then
echo "dashboard.json exists, deploying dashboard."
gcx resources push dashboards --path ./dashboard.json
else
echo "dashboard.json does not exist."
exit 1
fi
working-directory: ./github-actions-example
1. Извлечение кода и настройка Go
Чтобы настроить Go:
- Извлеките репозиторий, чтобы получить доступ к коду проекта.
- Установите Go 1.24.6 с помощью действия
actions/setup-go. - Убедитесь, что Go установлен правильно.
2. Загрузка и установка gcx
Далее загрузите CLI gcx с GitHub, используя версию, указанную в vars.GCX_VERSION. Он распаковывает архив, делает его исполняемым и перемещает в место в системном PATH.
3. Генерация JSON дашборда
Далее запустите генератор дашбордов (main.go) из каталога ./github-actions-example, чтобы создать файл dashboard.json, содержащий определение дашборда Grafana.
4. Развёртывание дашборда с помощью gcx
Если dashboard.json уже существует, он развёртывается в вашем экземпляре Grafana с помощью:
gcx resources push dashboards --path ./dashboard.json
Эта команда проходит аутентификацию в Grafana, используя следующие переменные среды:
GRAFANA_SERVER: URL вашего экземпляра GrafanaGRAFANA_STACK_ID: ID вашего стека GrafanaGRAFANA_TOKEN: токен сервисной учётной записи Grafana с достаточными правами
Используемые переменные и секреты GitHub
Убедитесь, что эти переменные настроены в вашем репозитории в разделе Settings > Security > Secrets and variables > Actions:
vars.GCX_VERSION: версияgcxдля установкиvars.GRAFANA_SERVER: URL вашего экземпляра Grafanavars.GRAFANA_STACK_ID: ID стека в Grafanasecrets.GRAFANA_TOKEN: токен API Grafana
Это действие гарантирует, что каждый push в main будет заново генерировать и развёртывать последнее определение вашего дашборда в Grafana.