-
Notifications
You must be signed in to change notification settings - Fork 127
Description
Describe the bug
When creating a dashboard with config_json = jsonencode(...) panels, the dashboard is created successfully (verified via GET /api/dashboards/{id}), but terraform reports:
Error: Provider produced inconsistent result after apply
.panels[0].config_json: was cty.StringVal("{...}"), but now cty.StringVal("{...}")
The API normalizes the config on read-back (adds defaults, reorders fields), so the JSON string returned differs from what was sent. The provider does a string comparison and treats any difference as an error.
To Reproduce
Resource: elasticstack_kibana_dashboard (experimental)
Provider: elastic/elasticstack (built from source)
- Fetch an existing dashboard via
GET /api/dashboards/{id} - Use the response's panel config verbatim in
config_json = jsonencode(...) terraform apply— creates the dashboard but errors on read-back
Example HCL (minimal)
resource "elasticstack_kibana_dashboard" "example" {
dashboard_id = "some-uuid"
title = "Example"
panels = [
{
type = "lens"
grid = { x = 0, y = 0, w = 24, h = 15 }
config_json = jsonencode({
"attributes" : {
"title" : "",
"type" : "xy",
# ... config from GET /api/dashboards/{id} response
}
})
},
]
}``
Error: Provider produced inconsistent result after apply
When applying changes to elasticstack_kibana_dashboard.example,
provider "provider["registry.terraform.io/elastic/elasticstack"]"
produced an unexpected new value: .panels[0].config_json: was
cty.StringVal("{"attributes":{...}}"),
but now cty.StringVal("{"attributes":{...}}")
The two JSON strings differ because the API added default values and/or reordered fields.
**Expected behavior**
The JSON string differences should not throw an error.
**Debug output**
Run `terraform` command with `TF_LOG=trace` and provide extended information on TF operations.
**Versions (please complete the following information):**
- macOS 26.3 (25D125)
- Terraform v1.14.2
- Provider version (pre-release build from commit c5145cc7)
- Elasticsearch snapshot version: 9.4.0
- Kibana running from source on commit `0f031101269f971dab9db848f965ce173245e2c7`
**Additional context**
Related to https://github.com/elastic/kibana-team/issues/2647
## Why we need `config_json`
We tried using the typed config attributes (`xy_chart_config`, `datatable_config`, `metric_config`, etc.) but they cause HTTP 400 validation errors on create. The typed Go struct serialization path omits fields that the Kibana OAS schema requires (e.g., a `filters` array when `operation` is `"filters"`, or other required defaults).
Using `config_json` avoids this entirely because it passes the panel config verbatim to the API. The config data comes directly from `GET /api/dashboards/{id}` — so it's already in the exact schema the API expects.
## Affected dashboards
All 15 dashboards in the `kibana-serverless-o11y-terraform` repo are affected. Every panel using `config_json` triggers this error.
## Suggested Fix
Semantic JSON comparison (parsed object equality) instead of string comparison for `config_json` in the read/plan logic. The relevant code is in:
- `internal/kibana/dashboard/models_panels.go` — `toAPI()` / read-back path
- The provider should parse both JSON strings and compare the resulting objects, not the raw strings
Alternatively, the provider could normalize the JSON (sort keys, strip server-added defaults) before comparison.
## Related: Typed config HTTP 400 errors
Separately from the read-back bug, the typed config attributes (`xy_chart_config`, `datatable_config`, etc.) cause HTTP 400 errors because the Go struct serialization doesn't include all required OAS fields. Examples:
- `operation: "filters"` rows need a `filters` array — typed converter omits it
- `operation: "formula"` metrics may be missing required fields
- Various default values the API expects but the typed structs don't populate
This forces users to `config_json` as a workaround, which then hits the read-back bug above.