Integrations

Terraform Provider

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

  1. Create an API token under Settings → API Tokens with read plus the create, update, and delete permissions you want Terraform to have
  2. Export it as SENTINEL_API_TOKEN (or set the provider's api_token argument from a variable)
  3. Add the provider and run terraform init

Full API access is included on every plan, so apply works on a free account within its monitor limit; API changes are budgeted per team per hour (30 on Free, 300 on paid plans), which is enough for an apply of a full roster.

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.

Billing recipients and invoice details

sentinel_billing declares the account's billing recipients (every paid invoice is emailed to them as a PDF) and the company, address and tax ID printed on invoices. It's a singleton, one per account, with the id billing; it belongs to the plan owner, so the provider's token has to be that account's. The resource declares the whole record: an attribute left out of the configuration is cleared on apply, and destroying the resource clears both blocks without deleting anything else.

resource "sentinel_billing" "account" {
  recipients = ["[email protected]", "[email protected]"]

  company       = "Example Company LLC"
  address_line1 = "1 Main St"
  city          = "Sacramento"
  state         = "CA"
  postal_code   = "95814"
  country       = "US"

  tax_id_type = "us_ein"
  tax_id      = "12-3456789"
}

Importing existing monitors

Billing imports with terraform import sentinel_billing.account billing. 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.