使用 CI/CD 自动化仪表盘配置
介绍
手动管理 Grafana 仪表盘效率低下且容易出错。正如您在入门指南中看到的那样,我们可以使用 Grafana Foundation SDK 通过强类型代码定义仪表盘。然后,我们可以将它们提交到版本控制,并使用 GitHub Actions 自动部署它们。
本指南将引导您了解
- 将 Grafana 仪表盘生成为代码
- 将其格式化为 Kubernetes 风格的部署
- 使用 GitHub Actions 部署仪表盘
- 检查仪表盘是否存在,如果存在则更新
最后,您对仪表盘代码的每一次更改都将在 Grafana 实例中自动创建或更新,无需手动干预。
1. 生成仪表盘 JSON
在部署仪表盘之前,我们需要使用 Grafana Foundation SDK 在代码中定义它。我们在入门指南中已经运行了一个示例,但是为了符合 Grafana 公开的 Kubernetes 资源兼容 API,我们将对代码进行一些更改,以适当的格式输出仪表盘 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/v1beta1",
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/v1beta1",
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${}`);
此脚本
- 生成 Grafana 仪表盘 JSON 文件
- 将其包装为 Kubernetes 风格的 API 格式(
apiVersion
、kind
、metadata
、spec
) - 将其保存为
dashboard.json
文件用于部署
2. 使用 GitHub Actions 自动化部署
接下来,我们将设置 GitHub Actions 来: 从 dashboard.json
中提取仪表盘名称 检查仪表盘是否已存在于我们的 Grafana 实例中 如果存在则更新,如果不存在则创建
注意
以下 GitHub Action 配置假设您使用的是基于 Go 的仪表盘生成器。如果您使用的是 Foundation SDK 支持的其他语言,请相应地修改 Generate Dashboard JSON (生成仪表盘 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 1.24.3
uses: actions/setup-go@v5
with:
go-version: 1.24.3
- name: Verify Go version
run: go version
- name: Download and Extract grafanactl
run: |
curl -L -o grafanactl-x86_64.tar.gz "https://github.com/grafana/grafanactl/releases/download/${{ vars.GRAFANACTL_VERSION }}/grafanactl_Linux_x86_64.tar.gz"
tar -xzf grafanactl-x86_64.tar.gz
chmod +x grafanactl
sudo mv grafanactl /usr/local/bin/grafanactl
- name: Generate Dashboard JSON
working-directory: ./github-actions-example
run: go run main.go
- name: Deploy Dashboard with grafanactl
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."
grafanactl resources push dashboards --path ./dashboard.json
else
echo "dashboard.json does not exist."
exit 1
fi
working-directory: ./github-actions-example
3. 说明此 GitHub Action
此 GitHub Action 使用 Foundation SDK 和 grafanactl
CLI 工具自动化部署 Grafana 仪表盘。
1. 检出并设置 Go
前几个步骤
- 检出仓库以访问项目代码。
- 使用
actions/setup-go
Action 安装 Go 1.24.3。 - 验证 Go 是否正确安装。
2. 下载并安装 grafanactl
此步骤使用 vars.GRAFANACTL_VERSION
中定义的版本从 GitHub 下载 grafanactl
CLI。它解压 tarball,使其可执行,并将其移动到系统 PATH
中的位置。
3. 生成仪表盘 JSON
从 ./github-actions-example
目录运行仪表盘生成器(main.go
)。这应该会生成一个包含 Grafana 仪表盘定义的 dashboard.json
文件。
4. 使用 grafanactl
部署仪表盘
如果 dashboard.json
存在,则使用以下命令部署到您的 Grafana 实例中:
grafanactl resources push dashboards --path ./dashboard.json
此命令使用以下环境变量针对 Grafana 进行身份验证:
GRAFANA_SERVER
:您的 Grafana 实例 URLGRAFANA_STACK_ID
:您的 Grafana 技术栈 IDGRAFANA_TOKEN
:具有足够权限的 Grafana 服务账户令牌
使用的 GitHub 变量和密钥
这些在您仓库的 **Settings → Security → Secrets and variables → Actions** (设置 → 安全 → 密钥和变量 → Actions) 下配置。
vars.GRAFANACTL_VERSION
:要安装的grafanactl
版本vars.GRAFANA_SERVER
:您的 Grafana 实例 URLvars.GRAFANA_STACK_ID
:Grafana 中的技术栈 IDsecrets.GRAFANA_TOKEN
:Grafana API 令牌
此 Action 确保每次推送到 main
分支时都会重新生成并将最新的仪表盘定义部署到 Grafana。
为什么要自动化?
自动化 Grafana 仪表盘部署消除了手动创建和更新仪表盘的需求,确保仪表盘在不同环境之间保持一致。通过将仪表盘定义为代码并通过 CI/CD(例如 GitHub Actions)进行管理,我们可以获得完整的版本控制,从而轻松跟踪随时间的变化并在需要时回滚。这也防止了重复,因为工作流会智能地检查仪表盘是否存在,然后再决定创建还是更新。通过这种完全自动化的 CI/CD 流水线,开发人员可以专注于改进他们的仪表盘,而不是手动上传 JSON 文件到 Grafana。
结论
通过将 Grafana Foundation SDK 与 GitHub Actions 集成,我们成功地自动化了 Grafana 仪表盘的整个生命周期。此设置允许我们以编程方式定义仪表盘,将其转换为 Kubernetes 兼容的格式,并自动部署它们。每次推送到仓库时,工作流都会确保仪表盘按需创建或更新。这不仅提高了效率,还确保了所有部署的仪表盘始终与最新的代码更改同步,从而减少了手动工作和潜在错误。