Developers

Terraform provider

Manage SutramX monitors, status pages and alert channels with Terraform using the sutramx/sutramx provider, with import and full argument reference.

The SutramX Terraform provider lets you manage monitors, status pages and alert channels next to the rest of your infrastructure, and read maintenance windows and escalation policies. It talks to the SutramX API with a workspace API key, and every resource lives in the workspace that key belongs to.

The provider is published on the Terraform Registry as sutramx/sutramx. Add it to required_providers as shown below and terraform init downloads it.

At a glance#

Source addresssutramx/sutramx on the Terraform Registry
Version~> 0.1 (0.1.0 is the current release)
Resourcessutramx_monitor, sutramx_status_page, sutramx_alert_channel
Data sourcessutramx_regions, sutramx_plans, sutramx_maintenance_windows, sutramx_escalation_policies
ImportMonitors by id or key; status pages and alert channels by id

Configure the provider#

Pin the provider to the 0.1 series, then run terraform init:

hcl
terraform {
  required_providers {
    sutramx = {
      source  = "sutramx/sutramx"
      version = "~> 0.1"
    }
  }
}

# The API key can also come from SUTRAMX_API_KEY.
provider "sutramx" {
  api_key = var.sutramx_api_key
}

variable "sutramx_api_key" {
  type      = string
  sensitive = true
}
ArgumentWhat it doesDefault
api_keySutramX API key (sk_...). Sensitive.SUTRAMX_API_KEY environment variable
api_urlAPI base URL. Must use https:// (plain http:// only for localhost).SUTRAMX_API_URL, else https://api.sutramx.com

The simplest setup is an empty provider "sutramx" {} block with SUTRAMX_API_KEY set in the environment.

Which API key you need#

Create a key in Account settings → API keys → Create API key. Whether you can create API keys, and how many, depends on your plan: see Plans & limits.

Every key has one of three access levels: Read-only (the dashboard default), Standard or Automation. The level is fixed when the key is created, so pick the one your configuration needs:

What you doLowest access level
terraform plan (refresh and data sources), for example in a plan-only CI job or for drift detectionRead-only. terraform apply with this key fails with 403 READ_ONLY_ACCESS.
Apply sutramx_monitor and sutramx_status_pageStandard
Apply sutramx_alert_channel, or a sutramx_monitor whose config_json sets notification_emails (per-monitor alert recipients)Automation
sutramx_maintenance_windows, sutramx_escalation_policiesRead-only
sutramx_regions, sutramx_plansNo key

Example#

hcl
resource "sutramx_monitor" "website" {
  key              = "web/home"
  name             = "Website"
  url              = "https://www.example.com"
  interval_seconds = 60
  regions          = ["fra1", "usa-az-probe"]
  tags             = ["prod", "web"]
  config_json = jsonencode({
    timeout               = 10000
    expected_status_codes = [200]
    keyword               = "Example Domain"
  })
}

resource "sutramx_monitor" "postgres" {
  key  = "infra/postgres"
  name = "Postgres"
  type = "port"
  config_json = jsonencode({
    host = "db.example.com"
    port = 5432
  })
}

resource "sutramx_status_page" "public" {
  title               = "Example status"
  slug                = "example-status"
  description         = "Live status of Example's website and API."
  is_public           = true
  show_response_times = true
  accent_color        = "#0d9488"

  monitors = [
    { monitor_id = sutramx_monitor.website.id },
    { monitor_id = sutramx_monitor.postgres.id, section = "Infrastructure" },
  ]
}

resource "sutramx_alert_channel" "ops_slack" {
  type = "slack"
  name = "Ops alerts"
  config = {
    webhook_url = var.slack_webhook_url
  }
  routing_scope = "monitors"
  monitor_ids   = [sutramx_monitor.website.id]
}

variable "slack_webhook_url" {
  type      = string
  sensitive = true
}

sutramx_monitor#

An uptime monitor. Checks run from SutramX probe regions; see Regions & confirmation for how regions confirm an outage.

ArgumentWhat it doesDefault / limits
nameDisplay name. Required.1–255 characters
keyStable key, unique in the workspace. The same key sutramx.yml uses.Generated (tf-...) when not set. 1–128 characters: letters, digits and . _ : / -, starting with a letter or digit
typehttp, api, ping, port, udp, cron, dns, multistep or mcp. Changing it replaces the monitor.http
urlTarget URL. Required for http, api and mcp monitors (mcp needs https://). Sensitive, so plans don't show it.Ping, port and UDP monitors use host, and DNS monitors hostname, in config_json
interval_secondsSeconds between checksPlan default; 15–900 and not below your plan's minimum
regionsSet of probe location codes, for example ["fra1", "usa-az-probe"] (see sutramx_regions)Omit for the plan's default locations. At least one; lower-case codes; order doesn't matter. Not allowed on cron monitors
tagsSet of tagsUp to 20, each 1–32 characters. Must be written in lower case, without leading or trailing spaces, or plan fails. Left untouched when omitted.
config_jsonType-specific settings as a JSON object string, usually with jsonencode(). Sensitive, so plans don't show it, and an output that uses it needs sensitive = trueManaged as a whole when set; left untouched when omitted (it then shows the stored settings)
pausedPause checksfalse
AttributeWhat it contains
idMonitor id (UUID)
heartbeat_urlFor cron monitors, the URL your job calls on each run. Sensitive.

What goes in config_json depends on the type: cron monitors need cron_expression; ping monitors need host; port and UDP monitors need host and port; DNS monitors need hostname (plus optional settings such as record_type and expected_values); multi-step checks need steps. Multi-step secrets are write-only: Terraform keeps your value and doesn't detect changes made elsewhere. HTTP and API monitors accept settings such as timeout, expected_status_codes, keyword, method and headers. See HTTP & keyword, API & multi-step checks, Ping, TCP & UDP, DNS, Heartbeat & cron and MCP servers for every option.

How it behaves:

  • Monitors are written with an idempotent create-or-update by key, so a retried apply never creates a duplicate.
  • config_json and tags that you leave out are not managed: whatever is set in the dashboard stays. Once you set config_json, it is managed as a whole, so keys you remove are removed from the monitor.
  • Unlike config_json and tags, leaving out regions means "use the plan's default locations".
  • Stored credentials in config_json (secret headers, tokens, passwords) are read back as [REDACTED]; Terraform keeps your configured values for them.
  • Per-monitor alert recipients (notification_emails in config_json) are ignored unless your configuration sets them. Setting them needs an Automation key; with any other key the apply fails with 403 ALERT_ROUTING_NOT_ALLOWED.
  • Changing type destroys the monitor (with its check history) and creates a new one.
  • Plan limits are enforced by the API exactly as in the dashboard. Errors such as ENTITLEMENT_LIMIT_REACHED appear as Terraform diagnostics.
  • terraform destroy deletes the monitor and its history.

Use the heartbeat URL of a cron monitor in your job:

hcl
resource "sutramx_monitor" "nightly_job" {
  key  = "jobs/nightly"
  name = "Nightly job"
  type = "cron"
  config_json = jsonencode({
    cron_expression = "0 2 * * *"
  })
}

output "nightly_job_heartbeat_url" {
  value     = sutramx_monitor.nightly_job.heartbeat_url
  sensitive = true
}

sutramx_status_page#

A status page showing the state of selected monitors. It counts against your plan's status page limit.

ArgumentWhat it doesDefault / limits
titlePage title. Required.1–255 characters
slugURL slugGenerated from the title when not set. 3–64 lower-case letters, digits or hyphens
descriptionText under the titleUp to 1000 characters; removed from the page when not set
is_publicWhether the page is publishedServer default when not set
logo_urlhttps:// image URLRemoved from the page when not set
accent_colorHex colour like #0d9488Removed from the page when not set
show_response_timesShow response times on the pageServer default when not set
hide_powered_byRemove SutramX brandingOnly on plans with white-label status pages
monitorsMonitors shown on the page, in display order: a list of { monitor_id, section }Omit to manage the list in the dashboard (the attribute then shows the current list)

In each monitors entry, monitor_id is required (usually sutramx_monitor.<name>.id) and section is an optional heading the monitor is grouped under.

The only attribute is id. Custom domains, private access and subscribers are managed in the dashboard: see Branding & custom domains. terraform destroy deletes the page.

sutramx_alert_channel#

An alert channel (integration connection) such as Slack, Discord, Microsoft Teams, a webhook, PagerDuty or Opsgenie. Creating, changing and deleting it requires an API key with the Automation access level. Which channel types you can use depends on your plan.

ArgumentWhat it doesDefault / limits
typeChannel type as shown in the dashboard's integration list, for example slack, discord, msteams, webhook, pagerduty, opsgenie or telegram. Changing it replaces the channel. Required.
nameDisplay name, unique among channels of the same type. Required.1–80 characters
configMap of the channel's fields, for example { webhook_url = var.slack_webhook_url } for Slack or { integration_key = ... } for PagerDuty. Sensitive. Required.
routing_scopeall (every monitor), groups (monitors in the groups in group_ids) or monitors (only monitor_ids)all
group_idsMonitor group ids this channel alerts for. Required when routing_scope = "groups", not allowed otherwiseUp to 500
monitor_idsMonitors this channel alerts for. Required when routing_scope = "monitors", not allowed otherwiseUp to 500
AttributeWhat it contains
idConnection id
statusConnection status reported by SutramX
signing_secretFor webhook channels, the secret SutramX signs payloads with. Only known when Terraform created the channel. Sensitive.
hcl
resource "sutramx_alert_channel" "incident_webhook" {
  type   = "webhook"
  name   = "Incident pipeline"
  config = { webhook_url = "https://hooks.example.com/sutramx" }
}

output "webhook_signing_secret" {
  value     = sutramx_alert_channel.incident_webhook.signing_secret
  sensitive = true
}

The fields each channel type needs are described in Slack, Teams & chat apps, Webhooks and PagerDuty & Opsgenie.

Data sources#

sutramx_regions#

SutramX probe locations. Use code in sutramx_monitor.regions. Doesn't need an API key. Which codes a monitor may use depends on your plan and billing market.

hcl
data "sutramx_regions" "online" {
  online_only = true
}

output "region_codes" {
  value = data.sutramx_regions.online.codes
}
NameKindWhat it contains
online_onlyOptional argumentOnly locations whose probes are online now
codesAttributeLocation codes, in activation order
regionsAttributeList of objects with code, name, city, country (ISO 3166-1 alpha-2), continent, latitude, longitude and online

sutramx_plans#

The current SutramX plans with prices and main limits, as listed on the pricing page. Doesn't need an API key.

hcl
data "sutramx_plans" "all" {}

output "plan_prices_usd" {
  value = { for plan in data.sutramx_plans.all.plans : plan.id => plan.price_monthly_usd }
}

Each entry in plans has id, name, description, markets (global for USD and/or india for INR), price_monthly_usd, price_annual_usd, price_monthly_inr, price_annual_inr, monitors, min_interval_seconds, probe_locations (null means every active location), status_pages (null means unlimited), api_keys (null means unlimited), popular and sort_order.

sutramx_maintenance_windows#

The workspace's maintenance windows, newest start first. Needs an API key; any access level works, including read-only. Terraform can only read windows: creating, changing and deleting them is done by the workspace owner in the dashboard, see Maintenance windows.

hcl
data "sutramx_maintenance_windows" "ongoing" {
  effective_status = "ongoing"
}

output "in_maintenance" {
  value = length(data.sutramx_maintenance_windows.ongoing.windows) > 0
}
NameKindWhat it contains
effective_statusOptional argumentOnly windows in this live state: scheduled, ongoing, completed or cancelled
idsAttributeIds of the returned windows, in order
windowsAttributeList of windows, described below

Each entry in windows has:

AttributeWhat it contains
id, title, descriptionThe window's id, title and description
statusStored status: scheduled, ongoing, completed or cancelled
effective_statusStatus worked out from the current time (the stored status can lag behind)
start_time, end_timeRFC 3339 times in UTC
timezoneIANA time zone the window was scheduled in
impactlow, medium or high
scope_typeglobal (every monitor), monitor or group
monitor_idsMonitors covered when scope_type is monitor
group_idsMonitor groups covered when scope_type is group
affected_servicesList of affected services
recurrence_typenone, daily or weekly
recurrence_weekdaysFor weekly windows, the days of the week (0 = Sunday)
recurrence_untilLast day a recurring window repeats; null when it repeats indefinitely or doesn't recur

sutramx_escalation_policies#

The workspace's escalation policies, newest first. Needs an API key; any access level works, including read-only. Terraform can only read policies: the workspace owner creates and changes them in the dashboard, see Escalation & on-call.

hcl
data "sutramx_escalation_policies" "primary" {
  name = "Primary on-call"
}

output "primary_policy_id" {
  value = one(data.sutramx_escalation_policies.primary.policies[*].id)
}
NameKindWhat it contains
nameOptional argumentOnly policies with exactly this name
policiesAttributeList of policies, described below

Each entry in policies has id, name, enabled, max_depth (how many steps an incident escalates through at most) and steps, in escalation order. Each step has:

AttributeWhat it contains
idStep id
step_orderPosition of the step
delay_minutesMinutes after the previous step before this one notifies
channelDelivery channel, for example email, slack or webhook
target_typeemail, on_call_primary, phone or integration
target_valueAddress, number or integration connection id the step notifies
target_labelReadable target, as shown in the dashboard

Import existing resources#

Monitors can be imported by id (UUID) or by key:

bash
# A monitor made in the dashboard: it gets a key on the next apply
terraform import sutramx_monitor.website 6f1c8f7e-6f2a-4a71-9d0b-0b8c1d2e3f40

# A monitor created by sutramx.yml or Terraform
terraform import sutramx_monitor.website web/home

Importing also fills in config_json, so a configuration that matches the monitor plans no changes. A dashboard monitor without a key gets one on the next apply: the key you set in HCL, or a generated tf-... key.

Status pages and alert channels are imported by id:

bash
terraform import sutramx_status_page.public 0b6f1c2a-9e4d-4f7a-8c3b-2d1e0f9a8b7c
terraform import sutramx_alert_channel.ops_slack 7d1e0f9a-8b7c-4c3b-9e4d-0b6f1c2a2d1e

Alert channel secrets aren't read back: set config in HCL and the next apply writes it.

Using Terraform with sutramx.yml#

The provider and the CLI use the same monitor keys. Pick one tool per monitor. If you use both in one workspace, don't turn on pruning in sutramx.yml: pruning deletes every keyed monitor that isn't in the file, including monitors created by Terraform.

Troubleshooting#

ProblemWhat to do
Authentication errorsSet SUTRAMX_API_KEY or api_key. Keys start with sk_.
sutramx_alert_channel fails with AUTOMATION_KEY_REQUIREDUse a key created with the Automation access level. A key's level can't be changed, so create a new key.
403 READ_ONLY_ACCESS on applyThe key is read-only, which only works for terraform plan. Use a Standard key, or Automation for alert channels and alert recipients.
ALERT_ROUTING_NOT_ALLOWEDA monitor's config_json sets notification_emails. Use an Automation key, or remove the field.
ENTITLEMENT_LIMIT_REACHED or FEATURE_NOT_AVAILABLEYour plan doesn't allow the change (monitor count, interval, locations, status pages or channel type). See Plans & limits.
Invalid tag (... has upper-case letters; SutramX stores tags lower-case)A tag has an upper-case letter or surrounding spaces. Write every tag in lower case, without spaces at the ends.
A plan wants to replace a monitorYou changed type. Replacing deletes the old monitor's history.

Last updated . Something unclear or missing on this page? Tell us at support@sutramx.com.