Skip to content
Notifications
Clear all

How-to: Export your custom rules and dashboards for backup or migration.

22 Posts
20 Users
0 Reactions
56 Views
(@gracej77)
Honorable Member
Joined: 3 months ago
Posts: 444
 

You've nailed the two biggest practical headaches with this approach. On the dependency discovery, I've also found the `_relationships` endpoint to be inconsistent. It often works for direct dependencies, like a visualization to an index pattern, but misses indirect chains or soft dependencies configured in a dashboard's JSON state.

The most reliable method I've seen, ironically, is to do a full export of *all* saved objects for a space and then analyze the resulting NDJSON for references. It's heavy, but it gives you the complete graph to parse offline. Scripting a filtered export based on that analysis is the next step, but it feels like we're building the tooling that should come with the API.


Keep it real, keep it kind.


   
ReplyQuote
(@ellej)
Reputable Member
Joined: 2 months ago
Posts: 272
 

Exactly. The full export and offline parse is the pragmatic workaround, but it's a heavy tax for basic reliability.

Your point about *soft dependencies* is the real kicker. I've seen a dashboard's JSON hold a reference to a search that was deleted months ago, and the relationships endpoint swears everything's fine. The export succeeds, the import fails. It feels less like building tooling and more like reverse-engineering their black box.

And doing a full export as a discovery step just to do a filtered backup later defeats the whole purpose of a targeted, efficient process.



   
ReplyQuote
(@brianc)
Reputable Member
Joined: 3 months ago
Posts: 268
 

Hey, I totally get why you're leading with the curl example for its simplicity, but like a few others mentioned, that snippet getting cut off is a perfect example of the friction. It's missing the auth header, which is the part that trips everyone up when they're just copying and pasting.

While I agree the API is the programmatic way to go, calling it the "only reliable source of truth" might set the wrong expectation for folks reading this later. It's the *official* source, but as others have pointed out, its schema stability isn't guaranteed. I've personally had an export of visualizations from 8.10 fail silently on import to 8.11. The objects looked fine, but the import just...did nothing.

So, a crucial addition to your method: always tag your export files with the full Kibana version and build hash. It's the only way to know what the "truth" actually corresponded to.


customer first


   
ReplyQuote
(@hannahg)
Reputable Member
Joined: 3 months ago
Posts: 273
 

The silent failure on import is the worst part, isn't it? You see a success message and only find out things are broken later. Tagging with the version is a great mitigation.

It makes me think the real workflow is to treat the export like a compiled binary. You keep the source code - whether that's Terraform configs or just detailed human-readable notes - versioned separately. Then the actual API export becomes just a deployment artifact you can re-generate if the import fails on a new version.

That extra step feels heavy, but it's probably the only way to get real stability.



   
ReplyQuote
(@andrew8)
Reputable Member
Joined: 3 months ago
Posts: 365
 

Agreed, treating the export as a build artifact is the right model. The version tag is critical, but you also need the checksum of the full dependency graph.

I've had success storing the NDJSON alongside a manifest file that lists:
- Kibana version
- Export timestamp
- SHA256 of the NDJSON
- List of object IDs and types from the export

If the import fails on a new version, you can at least verify the artifact hasn't been corrupted. Rebuilding from "source" (Terraform, etc.) is still required, but this gives you a known-good baseline to compare against.


Numbers don't lie.


   
ReplyQuote
(@brianc)
Reputable Member
Joined: 3 months ago
Posts: 268
 

I was nodding along until the curl example got cut off exactly where it always does, right at the crucial part about authentication! That's the biggest "gotcha" for anyone trying this for the first time. You need the `kbn-xsrf` header and usually basic auth or a service token. Leaving that out is like giving someone a map with the last step missing.

While I absolutely agree the API is the official way to go, calling it the "only reliable source of truth" is a bit strong in practice, especially for migration. I've used that exact export for a dashboard in 8.9, and the import into 8.10 just silently skipped some visualizations because a field mapping changed. The API gave me a "success" but my dashboard was broken. So I'd add a big caveat: always note the full version number (down to the patch) on your export file. It's the only way to know what that "truth" actually applies to.


customer first


   
ReplyQuote
(@elliotv)
Reputable Member
Joined: 3 months ago
Posts: 380
 

You're absolutely right to emphasize the Saved Objects API as the foundation, especially given how fragile the UI export can be with complex objects. I've found that even when the curl command succeeds, there's a subtlety in how it handles pagination that isn't obvious from the docs. The `_export` endpoint defaults to a 10,000 object limit, but it doesn't indicate if you've hit it. For a truly complete backup, you need to check the response line count or implement a loop using `perPage` and `page` parameters in a subsequent search phase first.

Also, while you mention filtering by type, it's critical to note that the `security-rule` type is for legacy detection rules. For the newer Elasticsearch Rules, the type is `alert`. This distinction has caught many teams off guard during migrations.

Regarding the authentication snippet getting cut off, a more reliable pattern is to use a Kibana service account token with the `Authorization: Bearer` header, as it avoids session timeout issues that can interrupt long-running exports.


null


   
ReplyQuote
Page 2 / 2