Manage dashboards as code
Store your dashboards as code, so you can review changes in pull requests, deploy them across spaces, clusters, and environments, and roll back by reverting a commit, instead of editing them by hand in each Kibana instance.
Elastic gives you two ways to define a dashboard as code:
- The Dashboards API produces a clean, diffable JSON definition that you can create and apply from any tool or language.
- The Elastic Stack Terraform provider builds on that API with a dashboard resource, so you can manage dashboards with Terraform alongside the rest of your infrastructure as code (IaC).
This workflow suits teams that want repeatable, auditable dashboard changes, and assumes you are comfortable with Git and your CI/CD system.
The same four stages apply whether you manage dashboards with the Dashboards API directly or with the Terraform provider:
| Stage | What happens | With the Dashboards API | With Terraform |
|---|---|---|---|
| Export | Produce a clean, diffable definition of the dashboard, without the internal state that makes raw saved objects hard to read. | Export the dashboard as API-compatible JSON. | Author the dashboard directly in HCL; there is no export step. |
| Store | Commit the definition to Git as the source of truth, so every change is tracked and you can roll back by reverting the commit. | Commit the exported JSON file. | Commit the .tf configuration. |
| Review | Review changes in a pull request before they ship. | Diff the structured JSON to see exactly which panel, query, or filter changed. | Diff the HCL, and run terraform plan to preview the change. |
| Deploy | Apply the definition to each target environment, reusing the same source to keep development, staging, and production in sync. | Send the definition to the Dashboards API in each environment. | Run terraform apply per environment or workspace. |
Once a dashboard is managed as code, treat Git as the single source of truth: changes made directly in the UI are overwritten the next time you deploy.
For the request schema and authentication details, refer to the Dashboards API reference.
The main challenge in moving a dashboard between spaces, clusters, or stages is that a dashboard and the objects it references, such as data views and library visualizations, are matched by ID. Because these IDs are auto-generated and differ across environments, a dashboard exported from one environment can point at objects that don't exist in another, and its panels show no data until the references resolve.
To keep a dashboard portable, choose one of the following approaches, listed from most to least automated.
If you already manage infrastructure as code, the Terraform provider handles ID consistency for you: it tracks each resource and maps IDs per environment, so references stay consistent as you promote a dashboard from development to production. Refer to Automate with Terraform.
The most portable way to build a panel is to define its visualization with ES|QL directly in the dashboard. This lets you:
- Keep the visualization definition inline, so it lives in the dashboard rather than pointing to a standalone library visualization that must already exist, with a matching ID, in the target environment.
- Query indices directly: an ES|QL query reads from the indices you name in it, so the panel doesn't rely on a separate saved data view that must already exist, with a matching ID, in the target environment.
The result carries no external references, so the dashboard stays fully portable. For a panel that can't use ES|QL, define it by value and back it with an ad-hoc data view to keep it just as self-contained.
If you keep references to saved objects, give each object the same ID in every environment so the references always resolve:
- Dashboards and library visualizations: create them with the Dashboards API and Visualizations API using
PUT(upsert) with a chosen ID (PUT /api/dashboards/{id}orPUT /api/visualizations/{id}), rather thanPOST, which generates a new ID each time. Because the exported definition already contains these IDs, re-importing it withPUTrecreates the same objects, with the same IDs, in the target environment. - Data views: create them with a chosen ID, either through the Data Views API by passing an
idin the POST request, or in the UI by setting a Custom data view ID. Use human-readable IDs, such aslogs-prod, so they are easy to reuse and recognize.
Regardless of the approach, to deploy a dashboard to a different space within the same cluster, include the destination space's ID in the request URL. The JSON export flow can open a pre-populated request in Kibana Dev Tools Console, where you set the destination space before sending it.
If you already manage your infrastructure with Terraform, the Elastic Stack Terraform provider includes an elasticstack_kibana_dashboard resource that manages dashboards through the Dashboards API. You define the dashboard in the provider's own configuration schema, then apply it like any other resource, so dashboard changes flow through terraform plan and terraform apply alongside the rest of your stack.
Because elasticstack_kibana_dashboard is a standard Terraform provider resource, other IaC tools that support Terraform providers can manage it too, including from languages other than HCL.
The provider documentation includes step-by-step guides with complete, runnable examples:
- Getting started with Kibana dashboards builds a web server logs dashboard one panel at a time, covering the layout grid and Lens metric, line, bar, and donut panels.
- Kibana dashboard operations guide adds pinned controls that filter every panel at once, a KPI row, a data table, and an embedded Discover session.
- Advanced Kibana dashboard patterns covers collapsible sections, image panels, ES|QL controls, access control, and tags.
This resource is in technical preview and still evolving. Keep two things in mind when you plan an adoption:
- There's no automatic conversion from an exported dashboard to Terraform. The JSON you export from a dashboard doesn't map to the resource's schema, so Terraform suits dashboards you author as code from the start rather than existing dashboards you want to bring in. You can place an existing dashboard under Terraform management with
terraform import, but you still write the matching configuration by hand. - Confirm the schema covers the panels you need. The resource doesn't yet expose every panel type and dashboard-level option that the Dashboards API supports.
For every attribute and panel type, refer to the elasticstack_kibana_dashboard resource reference.
To put this workflow into practice, choose the path that matches your tooling:
- Use the Dashboards API directly: see the Dashboards API reference for the request schema and authentication, or Create dashboards programmatically for an overview of the supported panel types and limits.
- Manage dashboards with Terraform: follow Getting started with Kibana dashboards to build your first dashboard as code.
For the background on this workflow and a worked Terraform example, see the Kibana dashboards as code: GitOps with Terraform blog (May 2026).