Terraform Provider
The official provider, rootstuff/sentinel on the
Terraform Registry,
manages monitors and webhook endpoints as code. Configuration lives in version
control, changes go through review, and terraform plan shows you any
drift between what's declared and what's actually configured.
Setup
- Create an API token under Settings → API Tokens with
readplus thecreate,update, anddeletepermissions you want Terraform to have - Export it as
SENTINEL_API_TOKEN(or set the provider'sapi_tokenargument from a variable) - Add the provider and run
terraform init
Full API access is included on the Pro and Business plans; Starter tokens are
read-only, which is enough for plan but not apply.
Example
terraform {
required_providers {
sentinel = {
source = "rootstuff/sentinel"
version = "~> 0.2"
}
}
}
provider "sentinel" {}
resource "sentinel_monitor" "storefront" {
url = "https://tickets.example.com"
friendly_name = "Ticketing Storefront"
check_interval = 1
check_types = ["ssl", "dns", "domain"]
domain_expiry_threshold = 30
}
resource "sentinel_webhook_endpoint" "incidents" {
name = "Incident tool"
url = var.incident_webhook_url
auth_type = "bearer"
auth_token = var.incident_webhook_token
severities = ["critical", "warning"]
}
Anything you don't set (regions, thresholds, intervals) uses the same defaults the dashboard applies, and the chosen values are recorded in state after the first apply.
Heartbeat and cron monitors
Push-based monitors are resources too, and the provider exposes each monitor's
ping_url as a sensitive output, so the dead-man wiring can live in the
same apply that creates the monitor:
resource "sentinel_monitor" "nightly_backup" {
monitor_type = "cron"
friendly_name = "Nightly backup"
heartbeat_cron_expression = "0 3 * * *"
heartbeat_grace = 900
}
output "backup_ping_url" {
value = sentinel_monitor.nightly_backup.ping_url
sensitive = true
}
Treat ping_url like a secret: anyone holding it can fake a healthy run.
Importing existing monitors
Monitors created in the dashboard can be adopted with
terraform import sentinel_monitor.name <id> (the id is in the
monitor's URL). Webhook endpoints import the same way; their secret fields
(url, auth_token, signing_secret) are never
returned by the API, so the first apply after an import resends them from your
configuration.
Good to know
- Domain expiry is tracked at the registrable domain, and one alert fires per team per domain no matter how many monitors share it, so it's safe to enable the domain check across a fleet of subdomains
- The provider talks to the versioned API (
/api/v1), which only changes additively within v1 - Deleting a resource from configuration deletes the monitor and its history on the next apply, exactly like deleting it in the dashboard
Resource-level attribute reference lives on the Registry documentation pages.