Description
What is the bug?
The OpenSearch Provider documentation for the opensearch_monitor
resource is out of sync with the actual API requirements. When using the documented structure, Terraform always reports drift and attempts to modify the resource on every plan, even when no changes are made.
It looks like most of the fields for which Terraform attempts modification do not need to be user accessible. Since the resource is fully defined through a JSON, it is not possible to ignore these changes using a lifecycle definition.
As a workaround, I was able to create a correct JSON structure which so far does not drift, attached below. This workaround is however brittle and not documented at the moment.
How can one reproduce the bug?
- Create an OpenSearch monitor following the documented structure from the provider documentation
- Run
terraform apply
to create the monitor - Run
terraform plan
without changing anything - Observe that Terraform shows differences and wants to update the monitor
What is the expected behavior?
After creating a monitor with Terraform, subsequent terraform plan
with no configuration changes should report "No changes." The provider should either:
- Transform the user-defined configuration to match OpenSearch's internal representation
- Or, correctly document the actual structure required by the OpenSearch API
What is your host/environment?
- OpenSearch 2.17
- terraform-provider-opensearch version 2.3.1
- macOS environment
Do you have any additional context?
The major discrepancies between documentation and required structure:
-
Undocumented required fields: Documentation doesn't mention
monitor_type
,owner
,data_sources
, anddelete_query_index_in_every_run
that the API adds. -
Trigger structure: Documentation shows a flat structure:
"triggers": [{"name": "trigger", "condition": {...}, "actions": [...]}]
But API requires:
"triggers": [{"query_level_trigger": {"name": "trigger", "condition": {...}, "actions": [...]}}]
-
Query format differences:
-
Documentation shows:
"range": {"time": {"gte": "now-24h", "lte": "now"}}
-
API requires:
"range": {"time": {"from": "now-24h", "to": "now", "include_lower": true, "include_upper": true, "boost": 1}}
-
Documentation shows:
"term": {"field": "value"}
-
API requires:
"term": {"field": {"value": "value", "boost": 1}}
-
Fixed working configuration example:
resource "opensearch_monitor" "example" {
body = jsonencode({
type = "monitor"
name = "example-monitor"
enabled = true
monitor_type = "query_level_monitor"
owner = "alerting"
data_sources = {
alerts_history_index = ".opendistro-alerting-alert-history-write"
alerts_history_index_pattern = "<.opendistro-alerting-alert-history-{now/d}-1>"
alerts_index = ".opendistro-alerting-alerts"
comments_index = ".opensearch-alerting-comments-history-write"
comments_index_pattern = "<.opensearch-alerting-comments-history-{now/d}-1>"
findings_enabled = false
findings_index = ".opensearch-alerting-finding-history-write"
findings_index_pattern = "<.opensearch-alerting-finding-history-{now/d}-1>"
query_index = ".opensearch-alerting-queries"
query_index_mappings_by_type = {}
}
delete_query_index_in_every_run = false
schedule = {
cron = {
expression = "0 8 * * *"
timezone = "UTC"
}
}
inputs = [{
search = {
indices = ["metrics-*"]
query = {
size = 0
query = {
bool = {
adjust_pure_negative = true
boost = 1
filter = [
{
range = {
time = {
boost = 1
from = "now-24h"
to = "now"
include_lower = true
include_upper = true
}
}
},
{
term = {
name = {
value = "documents_indexed_example-index"
boost = 1
}
}
}
]
}
}
aggregations = {
metric_value = {
"sum": {
field = "value"
}
}
}
}
}
}]
triggers = [{
query_level_trigger = {
id = "custom-trigger-id-123456" // Can be self-generated
name = "example-trigger"
severity = "1"
condition = {
script = {
source = "return ctx.results[0].aggregations.metric_value.value < 100"
lang = "painless"
}
}
actions = [{
id = "custom-action-id-123456" // Can be self-generated
name = "notify_sns"
destination_id = "your-destination-id"
message_template = {
source = "Alert: Value below threshold"
lang = "mustache"
}
subject_template = {
source = "[ENV] Metric Alert: example-monitor"
lang = "mustache"
}
throttle_enabled = false
}]
}
}]
})
}