Skip to content

Support sub-minute schedule values (10s, 30s) for synthetics monitors#1895

Open
shahzad31 wants to merge 1 commit intomainfrom
schedule-fix
Open

Support sub-minute schedule values (10s, 30s) for synthetics monitors#1895
shahzad31 wants to merge 1 commit intomainfrom
schedule-fix

Conversation

@shahzad31
Copy link
Copy Markdown

@shahzad31 shahzad31 commented Mar 13, 2026

Support sub-minute schedule values (10s, 30s) for synthetics monitors

Fixes elastic/kibana#232446

Summary

  • Adds support for sub-minute monitor schedules (0.1 for 10s, 0.5 for 30s) in the elasticstack_kibana_synthetics_monitor resource, addressing elastic/kibana#232446
  • Changes the schedule attribute from Int64 to Float64 to accept fractional values while maintaining backward compatibility with existing minute-based values (1, 3, 5, 10, 15, 30, 60, 120, 240)
  • Adds custom JSON marshaling on MonitorSchedule so that 0.1 serializes as "10s" and 0.5 as "30s" when sent to the Kibana API

Details

The Kibana Synthetics API recently added support for running monitors every 10 or 30 seconds. The API accepts these as string values ("10s", "30s") alongside the existing numeric minute values. Previously, the Terraform provider's schedule attribute was an integer, making it impossible to specify sub-minute intervals.

This change:

  • Updates MonitorSchedule type from int to float64 in the kbapi client library
  • Converts the TF schema schedule field from Int64Attribute to Float64Attribute
  • Maps 0.1 to/from "10s" and 0.5 to/from "30s" when communicating with the Kibana API
  • Adds unit tests for both sub-minute schedule values

Usage

resource "elasticstack_kibana_synthetics_monitor" "fast_check" {
  name     = "fast-check"
  schedule = 0.1  # every 10 seconds
  # ...
}

resource "elasticstack_kibana_synthetics_monitor" "medium_check" {
  name     = "medium-check"
  schedule = 0.5  # every 30 seconds
  # ...
}

@shahzad31 shahzad31 changed the title Support 0.1 and 0.5 values as schedule in synthetics monitor config Support sub-minute schedule values (10s, 30s) for synthetics monitors Mar 13, 2026
@shahzad31 shahzad31 marked this pull request as ready for review March 13, 2026 15:02
Copilot AI review requested due to automatic review settings March 13, 2026 15:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds sub-minute scheduling support for Kibana Synthetics monitors in the Terraform provider by allowing fractional schedule values and translating them to the new Kibana API string formats.

Changes:

  • Switches schedule from Int64 to Float64 in the TF model/schema and kbapi schedule type.
  • Adds schedule parsing from Kibana API (10s / 30s) into TF values (0.1 / 0.5).
  • Updates documentation and unit tests to cover the new schedule values.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
libs/go-kibana-rest/kbapi/api.kibana_synthetics.go Introduces float-based MonitorSchedule and custom JSON marshaling to emit "10s"/"30s".
internal/kibana/synthetics/monitor/schema.go Updates TF schema/model to Float64, adds API->TF schedule conversion, and updates request building.
internal/kibana/synthetics/monitor/schema_test.go Updates existing tests for float schedules and adds coverage for API->TF mapping of 10s/30s.
docs/resources/kibana_synthetics_monitor.md Documents newly supported schedule values 0.1 and 0.5.
docs/resources/elasticsearch_security_user.md Adjusts password write-only docs (appears unrelated to PR goal).
Comments suppressed due to low confidence (1)

internal/kibana/synthetics/monitor/schema_test.go:668

  • The updated schedule support adds special encoding for 0.1/0.5, but TestToKibanaAPIRequest still only covers minute-based schedules and only compares structs (it never asserts the JSON payload). Add test cases for schedules 0.1 and 0.5 and assert that marshaling the request/config produces the expected API values ("10s" / "30s").
			name: "HTTP monitor",
			input: tfModelV0{
				ID:               types.StringValue("test-id-http"),
				Name:             types.StringValue("test-name-http"),
				SpaceID:          types.StringValue("default"),
				Namespace:        types.StringValue("default-3"),
				Schedule:         types.Float64Value(5),
				Locations:        []types.String{types.StringValue("us_east")},
				PrivateLocations: []types.String{types.StringValue("test private location")},
				Enabled:          types.BoolPointerValue(tBool),
				Tags:             []types.String{types.StringValue("tag1"), types.StringValue("tag2")},
				Alert:            toAlertObject(t, tfAlertConfigV0{Status: &tfStatusConfigV0{Enabled: types.BoolPointerValue(tBool)}, TLS: &tfStatusConfigV0{Enabled: types.BoolPointerValue(fBool)}}),
				APMServiceName:   types.StringValue("test-service-http"),
				TimeoutSeconds:   types.Int64Value(30),
				Params:           jsontypes.NewNormalizedValue(`{"param1":"value1"}`),
				HTTP: &tfHTTPMonitorFieldsV0{
					URL:          types.StringValue("https://example.com"),
					MaxRedirects: types.Int64Value(5),
					Mode:         types.StringValue("all"),
					IPv4:         types.BoolPointerValue(tBool),
					IPv6:         types.BoolPointerValue(fBool),
					Username:     types.StringValue("user"),
					Password:     types.StringValue("pass"),
					ProxyHeader:  jsontypes.NewNormalizedValue(`{"header1":"value1"}`),
					ProxyURL:     types.StringValue("https://proxy.com"),
					Response:     jsontypes.NewNormalizedValue(`{"response1":"value1"}`),
					Check:        jsontypes.NewNormalizedValue(`{"check1":"value1"}`),
					tfSSLConfig: tfSSLConfig{
						SslVerificationMode: types.StringValue("full"),
						SslSupportedProtocols: types.ListValueMust(types.StringType, []attr.Value{
							types.StringValue("TLSv1.2"), types.StringValue("TLSv1.3"),
						}),
						SslCertificateAuthorities: []types.String{types.StringValue("cert1"), types.StringValue("cert2")},
						SslCertificate:            types.StringValue("cert"),
						SslKey:                    types.StringValue("key"),
						SslKeyPassphrase:          types.StringValue("passphrase"),
					},
				},
			},
			expected: kibanaAPIRequest{
				config: kbapi.SyntheticsMonitorConfig{
					Name:             "test-name-http",
					Schedule:         kbapi.MonitorSchedule(5),
					Locations:        []kbapi.MonitorLocation{"us_east"},

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread libs/go-kibana-rest/kbapi/api.kibana_synthetics.go
Comment thread internal/kibana/synthetics/monitor/schema.go
Comment thread docs/resources/elasticsearch_security_user.md Outdated
Comment thread docs/resources/elasticsearch_security_user.md
Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 16, 2026

@shahzad31 I've opened a new pull request, #1911, to work on those changes. Once the pull request is ready, I'll request review from you.

@tobio
Copy link
Copy Markdown
Member

tobio commented Mar 16, 2026

@shahzad31 IIRC these changes to the security user docs are a result of generating the docs with an old version of terraform.

Upgrading your local Terraform binary should solve the problem (or just revert the changes to that file).

},
},
"schedule": schema.Int64Attribute{
"schedule": schema.Float64Attribute{
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a big fan of the change here:

  • 0.1m != 10s, but also schedule = 0.1666666666 is obviously terrible.
  • We're just perpetuating a poor mapping between TF and API schemas.

I think it would be better to recognise the schema doesn't meet the API capabilities here and map things better. This gives us flexibility to adapt to other potential API changes as well.

IMO that means mimicking the API format more closely:

schedule = {
    unit = "s"
    number = 10
}

I think this gives us the best chance to maintain support if other scheduling options are added in the future.

Alternatively, we could turn schedule into a proper duration (e.g schedule = "10s") (via customtypes.DurationType) and keep the explicit OneOf validation on the allowed values. This would be a simpler breaking change, would avoid the weird fractional minutes, but wouldn't necessarily easily support other future scheduling options.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tobio i guess we could add a new field may be to make it bit more frictionless , but i agree , i guess it's likely not possible to suport number | string in schema

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, so there's a dynamic attribute which could work here.

In the past we've generally steered away from it because of the preference of Hashicorp. This case is very simple, so it's definitely not the worst approach and avoids a breaking change.

I'm happy if you want to explore that path. The other options involve a breaking schema change anyway, so the cost of a future change is similar if there's significant negative sentiment around dynamic.

@github-actions
Copy link
Copy Markdown
Contributor

⚠️ Terraform acceptance tests failed for snapshot stack version 9.4.0-SNAPSHOT.
This failure is non-blocking because snapshot builds are allowed to fail.

Run: https://github.com/elastic/terraform-provider-elasticstack/actions/runs/23200762362

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Synthetics] Inconsistent implementation of schedule parameter

4 participants