行业资讯
📅 2026/8/6 10:51:02
一次编辑,更新所有仪表板:使用 Terraform 大规模管理 Kibana 可观测性配置
作者来自 Elastic Jeffrey Rengifo只需在共享的 HCL 库中定义一次你的黄金信号golden signals面板然后使用for_each为每个团队生成对应的仪表板同时内置配置漂移检测和 Git 回滚能力。Elastic 提供了 Kibana Dashboards API 和原生 Terraform resource用于以代码方式管理仪表板。该能力在 Elastic 9.4 中以技术预览technical preview形式推出并在 Elastic 9.5 中正式发布GA。你只需要在 HCL 中定义一次黄金信号golden signals面板库然后通过for_each从该库为每个团队生成一个仪表板。当你需要修改错误阈值、面板布局或查询时只需提交一个 Pull Request就可以一次性更新所有团队的仪表板。如果发生配置漂移drift或出现问题你可以通过 Git 回滚进行恢复。为什么手动管理可观测性仪表板在大规模场景下会失效大型组织通常会拥有数百个仪表板。各团队会创建类似的面板并通过 Kibana UI 进行维护。当需要进行小范围修改时例如重命名面板、修复字段、添加新的错误阈值没有简单的方法可以将更改应用到所有仪表板中。你要么逐个打开每个仪表板在 UI 中进行编辑要么导出 NDJSON执行字符串替换然后重新导入。仪表板现在也是代码Elastic 提供了类型化的 Kibana Dashboards API 和原生的elasticstack_kibana_dashboard Terraform resource。你可以在 HCL 文件中定义一个仪表板然后像管理普通代码一样管理版本和变更。黄金信号仪表板一个定义供所有团队使用平台团队负责维护一个基于四个黄金信号golden signals构建的标准仪表板延迟latency、流量traffic、错误errors和饱和度saturation。每个团队都应该获得这个标准仪表板同时部分团队可以添加一两个自己的面板。我们的目标是只维护一个标准定义从该定义生成每个团队的仪表板一次修改即可同步到所有团队。前置条件运行 Elastic 9.4 或更高版本的 Elastic Cloud 部署或自建集群或者 Elastic Cloud Serverless 项目已安装 Terraform一个 Elasticsearch API key。本文使用的完整 Terraform 配置、初始化脚本seed script以及捕获的 Terraform plan 输出都可以在配套代码仓库中获取。配置 Elastic Terraform provider在其他 Terraform 文件旁边创建一个provider.tfterraform { required_providers { elasticstack { source elastic/elasticstack version ~ 0.11 } } } variable elasticsearch_endpoint { type string } variable elasticsearch_api_key { type string sensitive true } variable kibana_endpoint { type string } variable kibana_api_key { type string sensitive true } provider elasticstack { elasticsearch { endpoints [var.elasticsearch_endpoint] api_key var.elasticsearch_api_key } kibana { endpoints [var.kibana_endpoint] api_key var.kibana_api_key } }通过本地terraform.tfvars文件提供你的凭据并将其添加到.gitignore中以确保密钥不会进入代码仓库elasticsearch_endpoint https://...es.region.cloud.es.io elasticsearch_api_key ... kibana_endpoint https://...kb.region.cloud.es.io kibana_api_key ...只要该 API key 在目标 space 中具有仪表板写入权限dashboard write privileges你可以将同一个 API key 同时用于elasticsearch_api_key和kibana_api_key。然后初始化工作目录terraform init在 HCL 中定义单个团队的 Kibana 仪表板首先为单个团队创建一个基准仪表板。面板位于一个 48 列的网格布局中每个面板都是一个内联配置的 Lens 可视化对象。对于 KPI 卡片使用config_json它支持辅助指标和数值颜色配置对于时间序列图表使用xy_chart_config。将基础资源添加到新的dashboards.tf文件中resource elasticstack_kibana_dashboard golden_signals { title Golden Signals - payments description Latency, traffic, errors query { language kql, text } refresh_interval { pause false, value 60000 } time_range { from now-15m, to now } panels [ { type vis grid { x 0, y 0, w 12, h 5 } config_json jsonencode({ type metric data_source { type esql query FROM logs-payments-* | STATS 5xx errors COUNT(CASE(status 500, 1, null)) } metrics [{ type primary, column 5xx errors }] }) }, # More panels follow the same shape: other metric tiles, xy_chart_config line charts, and a breakdown datatable. See the companion repo for the full file. ] }每个面板都会设置类型和网格位置然后选择一种图表类型。KPI 卡片会将完整的 Lens 配置序列化到config_json中ES|QL 查询位于data_source下而指标列则通过metrics[*].column中的名称进行引用。仪表板的时间选择器time picker已经会自动限定 ES|QL 面板的数据范围因此查询中无需显式添加timestamp范围过滤条件。使用terraform plan预览 Kibana 仪表板变更运行terraform plan查看 Terraform 将要创建的内容terraform planplan 输出会列出新的elasticstack_kibana_dashboard.golden_signalsresource以及它将要设置的每个属性包括顶层仪表板字段以及每个面板对应的条目其中包含面板的网格位置、图表类型和数据源。Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: create Terraform will perform the following actions: # elasticstack_kibana_dashboard.golden_signals will be created resource elasticstack_kibana_dashboard golden_signals { description Latency, traffic, errors title Golden Signals - payments query { language kql, text } refresh_interval { pause false, value 60000 } time_range { from now-15m, to now } panels [ # Every panel described in full: KPI tiles (config_json), # line charts (xy_chart_config), and the breakdown datatable. ] } Plan: 1 to add, 0 to change, 0 to destroy.检查 plan 是在将任何内容发布到 Kibana 之前的最后一步。现在不要执行 apply。下一节会扩展该文件添加按团队生成的仪表板然后通过一次terraform apply部署所有内容。从共享面板库生成每个团队的可观测性仪表板在基础仪表板之上每个团队都会获得一组标准面板同时可以选择添加少量自己的面板。为每个团队硬编码一个 resource 的方式无法扩展。相反可以将面板库和团队映射定义为locals然后使用for_each构建仪表板。面板库中的每个条目都会描述一种图表类型、一个标题以及所需的数据resource 会根据chart_type自动生成对应的 Lens 配置块指标卡片使用config_json折线图使用xy_chart_config。将dashboards.tf的内容替换为locals { panel_library { errors { chart_type metric title Error rate esql_query_tpl FROM {idx} | STATS 5xx errors COUNT(CASE(status 500, 1, null)) esql_column 5xx errors } saturation { chart_type metric title Saturation (CPU) # Saturation reads from the metrics TSDB, so this query is not parameterized by {idx}. esql_query_tpl TS metrics-payments-* | STATS avg_cpu AVG(cpu.pct) esql_column avg_cpu } latency { chart_type xy title Latency p95 x_json jsonencode({ operation date_histogram field timestamp suggested_interval auto }) y_json jsonencode({ operation percentile field duration_ms percentile 95 }) } # ... more entries (traffic, cart_value) in the companion repo. } teams { payments { index logs-payments-* panels [errors, saturation, latency, traffic] } checkout { index logs-checkout-* panels [errors, cart_value, latency, traffic] } } } resource elasticstack_kibana_dashboard golden_signals { for_each local.teams title Golden Signals - ${each.key} description Latency, traffic, and errors for the ${each.key} service query { language kql, text } refresh_interval { pause false, value 60000 } time_range { from now-15m, to now } sections [ { title KPIs grid { y 0 } collapsed false panels [ for i, p in [for q in each.value.panels : q if local.panel_library[q].chart_type metric] : { type vis grid { x (i % 4) * 12, y 0, w 12, h 5 } config_json jsonencode({ ... }) # one metric tile per panel; see the companion repo for the full config } ] }, { title Trends grid { y 1 } collapsed false panels [ for i, p in [for q in each.value.panels : q if local.panel_library[q].chart_type xy] : { type vis grid { x (i % 3) * 16, y 0, w 16, h 10 } vis_config { by_value { xy_chart_config { ... } } } } ] }, # A third Breakdown section holds the request-by-status datatable. See the companion repo. ] }添加一个团队只需要在teams中增加一条配置。向所有团队添加一个面板只需要在panel_library中增加一条配置并在每个团队中添加一个引用。完整配置包括数据源 ES|QL 查询、指标、图层、坐标轴默认设置以及图例位置都位于dashboards.tf中。饱和度saturation面板会通过 ES|QL 的TS命令查询 metrics 数据流该命令专为 TSDB时间序列数据库设计。要使查询正常工作与metrics-payments-*匹配的数据流必须使用time_series模式因此配置中还提供了一个索引模板metrics_tsdb.tf用于启用该模式。使用terraform apply将代码形式的仪表板应用到 Kibana运行terraform plan确认将创建两个团队仪表板payments 和 checkout然后执行 applyterraform apply打开 Kibana你会看到每个团队都有一个黄金信号Golden Signals仪表板并且每个仪表板都由各自的索引模式index pattern支持。GitOps 流程中的代码化仪表板在 Pull Request 中审查变更现在仪表板已经成为版本控制中的一种资源就像其他基础设施一样。你可以编辑面板库或某个团队的配置选择然后创建一个 Pull Request。审查者可以查看 Terraform plan 的差异并了解哪些仪表板会发生变化。例如假设你将panel_library.errors.esql_query_tpl中的“严重错误”critical error阈值从status 500收紧为status 503。运行terraform plan后可以看到该变更会同时应用到两个团队注意完整输出请参见terraform-plan-update.txt。对panel_library.errors的一次修改会传播到所有引用它的团队。Pull Request 合并后就可以运行terraform apply。执行 apply 完成后刷新 Kibana 中的仪表板新阈值即可生效检测仪表板漂移并通过 Git 回滚如果有人通过 UI 编辑了仪表板下一次运行terraform plan时会显示差异因为代码状态和实际运行状态已经不再匹配。要实际体验这一点请在 Kibana 中打开Golden Signals - payments仪表板将Latency p95面板重命名为Latency p95 (EDITED)然后保存该仪表板。然后运行terraform planTerraform 会从实际运行中的仪表板读取面板标题将其与代码中的定义进行比较并提出撤销 UI 重命名的变更。你可以决定保留该修改更新代码以匹配实际状态或者通过运行terraform apply将其回滚。你可以提交新版本也可以使用 Git 回滚一个或多个版本。回顾之前的示例如果你重新打开修改panel_library.errors的 Pull Request该修改用于扩大错误阈值范围并添加更清晰的标题那么git diff dashboards.tf会用两行内容展示完整变更意图每个引用errors的团队都会在下一次terraform apply时获取新的阈值而回滚该提交会一次性将所有团队的变更恢复。总结手动管理 Kibana 可观测性仪表板无法在超过几个团队的规模下继续扩展。通过 Kibana Dashboards API 和 Terraform你可以一次定义标准通过共享面板库组合每个团队的仪表板并在 Pull Request 中审查每一次变更。一次编辑即可影响所有团队并且可以通过回滚提交来恢复变更。本文提出的文件结构只是众多组织方式中的一种你可以根据仪表板之间共享信息的程度以不同方式组织你的仪表板。后续步骤使用 Terraform 将 Kibana Dashboards 作为代码管理elasticstack_kibana_dashboard resource 参考文档Elastic Stack Terraform provider 文档Kibana Dashboards API 文档ES|QL 参考文档原文Kibana observability dashboards as code with Terraform — Elastic Observability Labs