Terraform & OpenTofu

Monitors that live next to your infrastructure.

Describe your checks and alert routing in code. Review them in a pull request, see every change in the plan, and apply them with the rest of your stack.

Checks and alert routing in code, reviewed in a pull request and applied with your stack.

culipulse/culipulsev0.1TerraformOpenTofu
monitoring.tfHCL
terraform {  required_providers {    culipulse = { source = "culipulse/culipulse", version = "~> 0.1" }  }}data "culipulse_agents" "singapore" {  kind   = "first_party"  region = "sg"}resource "culipulse_http_monitor" "api" {  name             = "API health"  url              = "https://api.example.com/health"  interval_seconds = 300  agent_ids        = data.culipulse_agents.singapore.ids  expected_status  = "200"  secret_headers   = { "X-Api-Key" = var.health_check_key }  assertions = [    { source = "json_body", op = "equals",      path = "$.status", value = "ok" },  ]}
resource "culipulse_http_monitor" "api" {  name             = "API health"  url              = "https://api.example.com/health"  interval_seconds = 300  expected_status  = "200"}

Get started

Three steps to your first plan.

1Create a token

In the console, open Settings → API tokens and create a read-and-write token.

Settings → API tokens
2Hand it to Terraform

Set it as an environment variable so it never lands in your code.

export CULIPULSE_API_TOKEN=cpk_…
3Plan and apply

Add the provider block, then run the usual commands. Nothing changes until you apply.

terraform init && terraform plan
$ terraform plandata.culipulse_agents.singapore: Reading...data.culipulse_agents.singapore: Read complete after 0sTerraform will perform the following actions:  # culipulse_channel_routing.incidents will be created  # culipulse_heartbeat_monitor.backup will be created  # culipulse_http_monitor.api will be created  + resource "culipulse_http_monitor" "api" {      + agent_ids           = ["agt_31f061d9-1aaf-430c-b85b-b63dad638cfa"]      + expected_status     = "200"      + interval_seconds    = 300      + url                 = "https://api.example.com/health"        …    }  # culipulse_webhook_channel.incidents will be createdPlan: 4 to add, 0 to change, 0 to destroy.
$ terraform plan  # culipulse_channel_routing.incidents will be created  # culipulse_heartbeat_monitor.backup will be created  # culipulse_http_monitor.api will be created  # culipulse_webhook_channel.incidents will be createdPlan: 4 to add, 0 to change, 0 to destroy.

Real terraform plan output against a CuliPulse test account (excerpt)Real plan output (excerpt)

What you can manage

Start with the checks you change most.

Version 0.1 covers website and scheduled-job monitors, webhooks and alert routing. Other monitor types stay in the console for now.

Resources
culipulse_http_monitorWebsite and API checks, with headers, sign-in details and response rules
culipulse_heartbeat_monitorScheduled-job check-ins, with the ping URL as an output
culipulse_webhook_channelA webhook destination and its signing secret
culipulse_channel_routingWhich monitors send alerts to which channel
Data sources
culipulse_agentsFind agents by kind and region, e.g. our Singapore agent
culipulse_channelLook up a Slack or Telegram channel you connected in the console

Not in Terraform yet

  • Port, UDP and ping monitors
  • DNS, domain and vendor status monitors
  • Connecting Slack or Telegram (connect once in the console)

Set these up in the console. Alert channels you connect there can still be used from Terraform.

Examples

Real configurations, ready to copy.

Send one monitor to a Telegram chat you connected in the console, and every monitor to your incident webhook.

Watch a nightly backup. Terraform hands you the ping URL to call as the last step of the job.

Already built monitors in the console? Bring them under Terraform by id, then add any secret headers to your config before the first apply.

More examples in the docs →
# A Telegram chat connected in the consoledata "culipulse_channel" "payments" {  name = "Payments team"  type = "telegram"}resource "culipulse_channel_routing" "payments" {  channel_id  = data.culipulse_channel.payments.id  monitor_ids = [culipulse_http_monitor.api.id]}# Every monitor, including ones created laterresource "culipulse_channel_routing" "incidents" {  channel_id   = culipulse_webhook_channel.incidents.id  all_monitors = true}
resource "culipulse_heartbeat_monitor" "backup" {  name = "Nightly backup"  interval_seconds = 86400  grace_seconds    = 1800}# Give this to your job, e.g. curl -fsS "$PING_URL"output "backup_ping_url" {  value     = culipulse_heartbeat_monitor.backup.ping_url  sensitive = true}
# The monitor id is in the console URL$ terraform import culipulse_http_monitor.api \    mon_3f2c9a1e-6b4d-4c8a-9f0e-1a2b3c4d5e6fculipulse_http_monitor.api: Importing...Import successful!

Add CuliPulse to your next plan.

Free account, one token, terraform init.