Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
MDX
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008---category: Referencetitle: Terraform Provider Referencedescription: Technical specification for the openstatus Terraform Provider.---
The openstatus Terraform provider lets you manage your monitoring infrastructure programmatically using HashiCorp Terraform. Define monitors, notification channels, and status pages as code โ with full support for version control, automated deployments, and IaC workflows.
**Key capabilities:**
- Manage HTTP, TCP, DNS, and ICMP monitors with assertions.- Configure notification channels (Slack, PagerDuty, email, webhooks, and more).- Create and manage status pages with component groups.- Provision private locations and assign monitors to them.- Import existing resources into Terraform state.
## Installation
Declare the provider in your Terraform configuration. Terraform will automatically download it when you run `terraform init`.
```terraformterraform { required_providers { openstatus = { source = "openstatusHQ/openstatus" version = "~> 0.1" } }}```
For the latest version, refer to the [Terraform Registry](https://registry.terraform.io/providers/openstatusHQ/openstatus/latest).
## Provider configuration
```terraformprovider "openstatus" { api_token = "YOUR_OPENSTATUS_API_TOKEN" # or set OPENSTATUS_API_TOKEN env var}```
| Argument | Type | Required | Description || :---------- | :------- | :------- | :-------------------------------------------------------------------------- || `api_token` | `string` | Yes | Your openstatus API token. Can also be set via the `OPENSTATUS_API_TOKEN` environment variable. || `base_url` | `string` | No | Base URL for the openstatus API. Defaults to `https://api.openstatus.dev/rpc`. |
## Resources
<Aside>gRPC monitors are not yet exposed as a Terraform resource. Manage them from the dashboard, the[ConnectRPC API](https://api.openstatus.dev/openapi), or the CLI until the provider catches up.</Aside>
### `openstatus_http_monitor`
Manages an HTTP monitor with support for custom headers, request bodies, and response assertions.
**Arguments:**
| Argument | Type | Required | Default | Description || :----------------- | :-------------- | :------- | :------- | :-------------------------------------------------------------------------- || `name` | `string` | Yes | | Monitor name (max 256 chars). || `url` | `string` | Yes | | URL to monitor (max 2048 chars). || `periodicity` | `string` | Yes | | Check frequency: `30s`, `1m`, `5m`, `10m`, `30m`, `1h`. || `method` | `string` | No | `"GET"` | HTTP method: `GET`, `POST`, `HEAD`, `PUT`, `PATCH`, `DELETE`, `OPTIONS`, `TRACE`, `CONNECT`. || `body` | `string` | No | `""` | Request body for `POST`, `PUT`, `PATCH` methods. || `timeout` | `number` | No | `45000` | Timeout in milliseconds (0โ120000). || `degraded_at` | `number` | No | computed | Response time threshold (ms) after which the monitor is considered degraded. || `retry` | `number` | No | `3` | Number of retries on failure (0โ10). || `follow_redirects` | `bool` | No | `true` | Whether to follow HTTP redirects. || `active` | `bool` | No | `false` | Whether the monitor is active. || `public` | `bool` | No | `false` | Whether the monitor is visible on your public status page. || `description` | `string` | No | | Monitor description (max 1024 chars). || `regions` | `set(string)` | No | | Regions to monitor from. See [Available Regions](#available-regions). |
**Blocks:**
- **`headers`** (max 20) โ Custom HTTP headers to include with each request. - `key` (string, required) โ Header name. - `value` (string, required) โ Header value.
- **`status_code_assertions`** (max 10) โ Assert on response status codes. - `target` (number, required) โ Expected status code (100โ599). - `comparator` (string, required) โ One of: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`.
- **`body_assertions`** (max 10) โ Assert on response body content. - `target` (string, required) โ Expected value. - `comparator` (string, required) โ One of: `contains`, `not_contains`, `eq`, `neq`, `empty`, `not_empty`, `gt`, `gte`, `lt`, `lte`.
- **`header_assertions`** (max 10) โ Assert on response headers. - `key` (string, required) โ Header name to assert on. - `target` (string, required) โ Expected value. - `comparator` (string, required) โ Same comparators as `body_assertions`.
- **`open_telemetry`** โ Export this monitor's metrics to an OTLP endpoint (HTTP only). - `endpoint` (string, optional) โ OTLP metrics endpoint URL. - `headers` (block list, optional) โ Headers sent with each export; each has a required `key` and `value`.
**Read-only attributes:** `id` (string), `status` (string: `active`, `degraded`, `error`, `unknown`), `private_location_ids` (set of string โ managed from `openstatus_private_location.monitor_ids`).
**Example โ Basic health check:**
```terraformresource "openstatus_http_monitor" "website" { name = "Website Availability" url = "https://www.example.com" periodicity = "1m" active = true public = true regions = ["fly-iad", "fly-ams", "fly-syd"]}```
**Example โ API monitor with assertions and headers:**
```terraformresource "openstatus_http_monitor" "api" { name = "API Health Check" description = "Monitors the /health endpoint with full assertions." url = "https://api.example.com/health" periodicity = "5m" method = "GET" timeout = 30000 active = true regions = ["fly-iad", "fly-ams", "fly-nrt"]
headers { key = "Authorization" value = "Bearer ${var.api_token}" }
headers { key = "Accept" value = "application/json" }
status_code_assertions { target = 200 comparator = "eq" }
body_assertions { target = "ok" comparator = "contains" }
header_assertions { key = "Content-Type" target = "application/json" comparator = "contains" }}```
**Example โ POST monitor with request body:**
```terraformresource "openstatus_http_monitor" "webhook" { name = "Webhook Endpoint" url = "https://api.example.com/webhooks/health" periodicity = "10m" method = "POST" active = true regions = ["fly-iad"]
headers { key = "Content-Type" value = "application/json" }
body = jsonencode({ type = "health_check" })
status_code_assertions { target = 202 comparator = "eq" }}```
**Import:**
```bashterraform import openstatus_http_monitor.website <monitor_id>```
---
### `openstatus_tcp_monitor`
Manages a TCP connection monitor to verify that a port is open and reachable.
**Arguments:**
| Argument | Type | Required | Default | Description || :------------ | :------------ | :------- | :------- | :----------------------------------------------------------------- || `name` | `string` | Yes | | Monitor name (max 256 chars). || `uri` | `string` | Yes | | Target in `host:port` format (max 2048 chars). || `periodicity` | `string` | Yes | | Check frequency: `30s`, `1m`, `5m`, `10m`, `30m`, `1h`. || `timeout` | `number` | No | `45000` | Timeout in milliseconds (0โ120000). || `degraded_at` | `number` | No | computed | Degradation threshold in milliseconds. || `retry` | `number` | No | `3` | Number of retries on failure (0โ10). || `active` | `bool` | No | `false` | Whether the monitor is active. || `public` | `bool` | No | `false` | Whether the monitor is publicly visible. || `description` | `string` | No | | Monitor description (max 1024 chars). || `regions` | `set(string)` | No | | Regions to monitor from. See [Available Regions](#available-regions). |
**Blocks:**
- **`open_telemetry`** โ Export this monitor's metrics to an OTLP endpoint (HTTP only). - `endpoint` (string, optional) โ OTLP metrics endpoint URL. - `headers` (block list, optional) โ Headers sent with each export; each has a required `key` and `value`.
**Read-only attributes:** `id` (string), `status` (string), `private_location_ids` (set of string โ managed from `openstatus_private_location.monitor_ids`).
**Example โ Database port check:**
```terraformresource "openstatus_tcp_monitor" "database" { name = "PostgreSQL Port Check" description = "Ensures the database port is open and reachable." uri = "db.example.com:5432" periodicity = "1m" timeout = 10000 active = true regions = ["fly-iad", "fly-fra"]}```
**Example โ Redis monitor:**
```terraformresource "openstatus_tcp_monitor" "redis" { name = "Redis Connection" uri = "redis.example.com:6379" periodicity = "30s" active = true regions = ["fly-iad", "fly-ams", "fly-nrt"]}```
**Import:**
```bashterraform import openstatus_tcp_monitor.database <monitor_id>```
---
### `openstatus_dns_monitor`
Manages a DNS monitor with support for record type assertions.
**Arguments:**
| Argument | Type | Required | Default | Description || :------------ | :------------ | :------- | :------- | :----------------------------------------------------------------- || `name` | `string` | Yes | | Monitor name (max 256 chars). || `uri` | `string` | Yes | | Domain name to monitor (max 2048 chars). || `periodicity` | `string` | Yes | | Check frequency: `30s`, `1m`, `5m`, `10m`, `30m`, `1h`. || `timeout` | `number` | No | `45000` | Timeout in milliseconds (0โ120000). || `degraded_at` | `number` | No | computed | Degradation threshold in milliseconds. || `retry` | `number` | No | `3` | Number of retries on failure (0โ10). || `active` | `bool` | No | `false` | Whether the monitor is active. || `public` | `bool` | No | `false` | Whether the monitor is publicly visible. || `description` | `string` | No | | Monitor description (max 1024 chars). || `regions` | `set(string)` | No | | Regions to monitor from. See [Available Regions](#available-regions). |
**Blocks:**
- **`record_assertions`** (max 10) โ Assert on DNS record values. - `record` (string, required) โ DNS record type: `A`, `AAAA`, `CNAME`, `MX`, `TXT`. - `target` (string, required) โ Expected value. - `comparator` (string, required) โ One of: `eq`, `neq`, `contains`, `not_contains`.
- **`open_telemetry`** โ Export this monitor's metrics to an OTLP endpoint (HTTP only). - `endpoint` (string, optional) โ OTLP metrics endpoint URL. - `headers` (block list, optional) โ Headers sent with each export; each has a required `key` and `value`.
**Read-only attributes:** `id` (string), `status` (string), `private_location_ids` (set of string โ managed from `openstatus_private_location.monitor_ids`).
**Example โ A record validation:**
```terraformresource "openstatus_dns_monitor" "main_domain" { name = "DNS A Record Check" description = "Verifies that example.com resolves to the correct IP." uri = "example.com" periodicity = "10m" active = true regions = ["fly-iad", "fly-ams"]
record_assertions { record = "A" comparator = "eq" target = "93.184.216.34" }}```
**Example โ MX record validation:**
```terraformresource "openstatus_dns_monitor" "email" { name = "Email MX Record Check" uri = "example.com" periodicity = "30m" active = true regions = ["fly-iad"]
record_assertions { record = "MX" comparator = "contains" target = "mail.example.com" }}```
**Import:**
```bashterraform import openstatus_dns_monitor.main_domain <monitor_id>```
---
### `openstatus_icmp_monitor`
Manages an ICMP (ping) monitor that checks host reachability and round-trip latency.
**Arguments:**
| Argument | Type | Required | Default | Description || :------------ | :------------ | :------- | :------- | :----------------------------------------------------------------- || `name` | `string` | Yes | | Monitor name (max 256 chars). || `uri` | `string` | Yes | | Target host or IP address to ping, without a port. || `periodicity` | `string` | Yes | | Check frequency: `30s`, `1m`, `5m`, `10m`, `30m`, `1h`. || `timeout` | `number` | No | `45000` | Budget in milliseconds for the whole check (0โ120000). || `degraded_at` | `number` | No | computed | Average-latency threshold in milliseconds. || `retry` | `number` | No | `3` | Number of retries on a fully failed check (0โ10). || `active` | `bool` | No | `false` | Whether the monitor is active. || `public` | `bool` | No | `false` | Whether the monitor is publicly visible. || `description` | `string` | No | | Monitor description (max 1024 chars). || `regions` | `set(string)` | No | | Regions to monitor from. See [Available Regions](#available-regions). |
**Blocks:**
- **`open_telemetry`** โ Export this monitor's metrics to an OTLP endpoint (HTTP only). - `endpoint` (string, optional) โ OTLP metrics endpoint URL. - `headers` (block list, optional) โ Headers sent with each export; each has a required `key` and `value`.
**Read-only attributes:** `id` (string), `status` (string), `private_location_ids` (set of string โ managed from `openstatus_private_location.monitor_ids`).
See the [ICMP monitor reference](/docs/reference/icmp-monitor) for how a check is run (three echo requests, average latency, packet loss).
**Example โ Gateway reachability:**
```terraformresource "openstatus_icmp_monitor" "gateway" { name = "Gateway Ping" description = "Round-trip latency to the upstream gateway." uri = "8.8.8.8" periodicity = "1m" timeout = 10000 active = true regions = ["fly-iad", "fly-fra"]
open_telemetry { endpoint = "https://otel.example.com/v1/metrics" }}```
**Import:**
```bashterraform import openstatus_icmp_monitor.gateway <monitor_id>```
---
### `openstatus_notification`
Manages a notification channel. Supports 12 provider types: Discord, Email, Slack, PagerDuty, OpsGenie, Webhook, Telegram, WhatsApp, Google Chat, Grafana OnCall, Microsoft Teams, and ntfy.
**Arguments:**
| Argument | Type | Required | Description || :-------------- | :------------ | :------- | :------------------------------------------------------ || `name` | `string` | No | Notification channel name. || `provider_type` | `string` | Yes | Provider type (see supported values below). || `monitor_ids` | `set(string)` | No | Set of monitor IDs to associate with this notification. |
**Supported `provider_type` values:** `discord`, `email`, `slack`, `pagerduty`, `opsgenie`, `webhook`, `telegram`, `whatsapp`, `google_chat`, `grafana_oncall`, `ms_teams`, `ntfy`.
**Provider-specific blocks** โ use exactly one block matching your `provider_type`:
| Block | Arguments || :-------------- | :----------------------------------------------------------------------------------------------------- || `discord` | `webhook_url` (string, required, sensitive) || `email` | `email` (string, required) || `slack` | `webhook_url` (string, required, sensitive) || `pagerduty` | `integration_key` (string, required, sensitive) || `opsgenie` | `api_key` (string, required, sensitive), `region` (string, required: `us` or `eu`) || `webhook` | `endpoint` (string, required), `headers` (optional list of `key`/`value` objects) || `telegram` | `chat_id` (string, required) || `whatsapp` | `phone_number` (string, required) || `google_chat` | `webhook_url` (string, required, sensitive) || `grafana_oncall` | `webhook_url` (string, required, sensitive) || `ms_teams` | `webhook_url` (string, required, sensitive) || `ntfy` | `topic` (string, required), `server_url` (string, optional), `token` (string, optional, sensitive) |
**Read-only attributes:** `id` (string), `created_at` (string), `updated_at` (string).
**Example โ Slack notification:**
```terraformresource "openstatus_notification" "slack_alerts" { name = "Slack Alerts" provider_type = "slack" monitor_ids = [openstatus_http_monitor.api.id]
slack { webhook_url = var.slack_webhook_url }}```
**Example โ PagerDuty notification:**
```terraformresource "openstatus_notification" "pagerduty" { name = "PagerDuty Escalation" provider_type = "pagerduty" monitor_ids = [ openstatus_http_monitor.api.id, openstatus_tcp_monitor.database.id, ]
pagerduty { integration_key = var.pagerduty_key }}```
**Example โ Email notification:**
```terraformresource "openstatus_notification" "email" { name = "On-Call Email" provider_type = "email" monitor_ids = [openstatus_http_monitor.api.id]
email { email = "oncall@example.com" }}```
**Example โ Custom webhook:**
```terraformresource "openstatus_notification" "custom_webhook" { name = "Custom Webhook" provider_type = "webhook"
webhook { endpoint = "https://api.example.com/alerts"
headers { key = "Authorization" value = "Bearer ${var.webhook_token}" }
headers { key = "Content-Type" value = "application/json" } }}```
**Example โ Discord notification:**
```terraformresource "openstatus_notification" "discord" { name = "Discord Alerts" provider_type = "discord"
discord { webhook_url = var.discord_webhook_url }}```
**Import:**
```bashterraform import openstatus_notification.slack_alerts <notification_id>```
---
### `openstatus_status_page`
Manages a status page with access control and branding.
**Arguments:**
| Argument | Type | Required | Description || :------------------- | :------------- | :------- | :----------------------------------------------------------------------------- || `title` | `string` | Yes | Page title (1โ256 chars). || `slug` | `string` | Yes | URL slug (1โ256 chars). Used in the status page URL. || `description` | `string` | No | Page description (max 1024 chars). || `homepage_url` | `string` | No | Link to your homepage. || `contact_url` | `string` | No | Link to your contact page. || `icon` | `string` | No | URL of the icon to display. || `custom_domain` | `string` | No | Custom domain (DNS must point to openstatus first). || `access_type` | `string` | No | Access control: `public`, `password`, `email-domain`, or `ip-restriction`. || `password` | `string` | No | Required when `access_type` is `password`. Sensitive. || `auth_email_domains` | `list(string)` | No | Required when `access_type` is `email-domain`. || `allowed_ip_ranges` | `string` | No | Comma-separated IPv4 CIDR ranges. Required when `access_type` is `ip`. || `theme` | `string` | No | Theme key applied to the page. || `custom_theme` | `object` | No | Per-mode CSS variable overrides merged over `theme`, with `light` and `dark` maps. Requires the custom-theme plan feature. || `default_locale` | `string` | No | Default language for the page. || `locales` | `list(string)` | No | Locales offered in the language switcher. || `allow_index` | `bool` | No | Whether search engines may index the page. |
**Read-only attributes:** `id` (string), `published` (bool), `created_at` (string), `updated_at` (string).
**Example โ Public status page:**
```terraformresource "openstatus_status_page" "main" { title = "Example Inc. Status" slug = "example-status" description = "Real-time status for all Example Inc. services." homepage_url = "https://example.com" contact_url = "https://example.com/support"}```
**Example โ Password-protected status page:**
```terraformresource "openstatus_status_page" "internal" { title = "Internal Status" slug = "internal-status" description = "Status page for internal services." access_type = "password" password = var.status_page_password}```
**Example โ Email-domain restricted status page:**
```terraformresource "openstatus_status_page" "company" { title = "Company Status" slug = "company-status" access_type = "email-domain" auth_email_domains = ["example.com", "subsidiary.com"]}```
**Example โ IP-restricted status page:**
```terraformresource "openstatus_status_page" "internal" { title = "Internal Status" slug = "internal-status" access_type = "ip-restriction" allowed_ip_ranges = "10.0.0.0/8,192.168.0.0/16"}```
**Import:**
```bashterraform import openstatus_status_page.main <page_id>```
---
### `openstatus_status_page_component`
Manages a component on a status page. Components can be linked to a monitor or be static.
**Arguments:**
| Argument | Type | Required | Description || :------------ | :------- | :------- | :--------------------------------------------------------------------------- || `page_id` | `string` | Yes | Status page ID this component belongs to. Forces replacement if changed. || `type` | `string` | Yes | Component type: `monitor` or `static`. Forces replacement if changed. || `monitor_id` | `string` | No | Required when `type` is `monitor`. The monitor ID to display. || `name` | `string` | No | Component display name (max 256 chars). || `description` | `string` | No | Component description (max 1024 chars). || `order` | `number` | No | Display order on the status page. || `group_id` | `string` | No | Component group ID this belongs to. || `group_order` | `number` | No | Display order within its group. |
**Read-only attributes:** `id` (string), `created_at` (string), `updated_at` (string).
**Example โ Monitor component:**
```terraformresource "openstatus_status_page_component" "api" { page_id = openstatus_status_page.main.id type = "monitor" monitor_id = openstatus_http_monitor.api.id name = "API" order = 1}```
**Example โ Static component:**
```terraformresource "openstatus_status_page_component" "third_party" { page_id = openstatus_status_page.main.id type = "static" name = "Third-party Services" description = "Status of external dependencies." order = 2}```
**Import:**
```bashterraform import openstatus_status_page_component.api <page_id>/<component_id>```
---
### `openstatus_status_page_component_group`
Manages a component group on a status page, allowing you to organize components visually.
**Arguments:**
| Argument | Type | Required | Description || :-------- | :------- | :------- | :----------------------------------------------------------------------- || `page_id` | `string` | Yes | Status page ID this group belongs to. Forces replacement if changed. || `name` | `string` | Yes | Group name (1โ256 chars). |
**Read-only attributes:** `id` (string), `created_at` (string), `updated_at` (string).
**Example:**
```terraformresource "openstatus_status_page_component_group" "infrastructure" { page_id = openstatus_status_page.main.id name = "Infrastructure"}
resource "openstatus_status_page_component_group" "applications" { page_id = openstatus_status_page.main.id name = "Applications"}```
**Import:**
```bashterraform import openstatus_status_page_component_group.infrastructure <page_id>/<group_id>```
---
### `openstatus_private_location`
Manages a private location: a self-hosted checker agent that runs the monitors you assign to it.
Terraform owns `monitor_ids` and `metadata` โ removing either from the configuration clears it on the next apply. Liveness (`status`, `last_seen_at`) is only available on the `openstatus_private_location` data source.
**Arguments:**
| Argument | Type | Required | Description || :------------ | :------------ | :------- | :----------------------------------------------------------- || `name` | `string` | Yes | Display name for the private location. || `monitor_ids` | `set(string)` | No | IDs of the monitors this private location runs. || `metadata` | `map(string)` | No | User-defined key/value labels attached to this location. |
**Read-only attributes:** `id` (string), `token` (string, sensitive), `created_at` (string), `updated_at` (string).
```terraformresource "openstatus_private_location" "eu_dc" { name = "EU Datacenter" monitor_ids = [openstatus_http_monitor.api.id]
metadata = { env = "prod" region = "eu-west-1" }}
# The agent token is generated by openstatus. Pass it to the checker agent.output "agent_token" { value = openstatus_private_location.eu_dc.token sensitive = true}```
## Data Sources
### `openstatus_monitor`
Look up a single monitor by ID. Works for HTTP, TCP, DNS, and ICMP monitors.
```terraformdata "openstatus_monitor" "existing" { id = "123"}
output "monitor_name" { value = data.openstatus_monitor.existing.name}
output "monitor_type" { value = data.openstatus_monitor.existing.type}```
**Computed attributes:** `type` (`http`, `tcp`, `dns`, `icmp`), `name`, `url` (HTTP only), `uri` (TCP/DNS/ICMP only), `periodicity`, `method` (HTTP only), `active`, `public`, `description`, `timeout`, `status`, `private_location_ids`.
---
### `openstatus_monitors`
List all monitors with pagination.
```terraformdata "openstatus_monitors" "all" { limit = 100 offset = 0}
output "total_monitors" { value = length(data.openstatus_monitors.all.monitors)}```
| Argument | Type | Required | Default | Description || :------- | :------- | :------- | :------ | :----------------------- || `limit` | `number` | No | `50` | Max results (1โ100). || `offset` | `number` | No | `0` | Pagination offset. |
**Computed:** `monitors` โ list of objects with `id`, `name`, `type`.
---
### `openstatus_notification`
Look up a notification channel by ID.
```terraformdata "openstatus_notification" "existing" { id = "456"}
output "notification_provider" { value = data.openstatus_notification.existing.provider_type}```
**Computed attributes:** `name`, `provider_type`, `monitor_ids`, `created_at`, `updated_at`.
---
### `openstatus_status_page`
Look up a status page by ID.
```terraformdata "openstatus_status_page" "existing" { id = "789"}
output "status_page_url" { value = data.openstatus_status_page.existing.slug}```
**Computed attributes:** `title`, `slug`, `description`, `homepage_url`, `contact_url`, `icon`, `custom_domain`, `published`, `access_type`, `password` (sensitive), `auth_email_domains`, `theme`, `created_at`, `updated_at`.
---
### `openstatus_private_location`
Look up a single private location by ID. Unlike the resource, this data source exposes agent liveness.
```terraformdata "openstatus_private_location" "eu_dc" { id = "12"}
output "agent_last_seen" { value = data.openstatus_private_location.eu_dc.last_seen_at}```
**Computed attributes:** `name`, `monitor_ids`, `metadata`, `status` (`active`, `error`, or `unknown`), `last_seen_at` (RFC 3339, null if the agent has never reported), `token` (sensitive), `created_at`, `updated_at`.
---
### `openstatus_private_locations`
List all private locations with pagination.
```terraformdata "openstatus_private_locations" "all" { limit = 100}
output "private_location_names" { value = [for l in data.openstatus_private_locations.all.private_locations : l.name]}```
| Argument | Type | Required | Default | Description || :------- | :------- | :------- | :------ | :----------------- || `limit` | `number` | No | `50` | Max results. || `offset` | `number` | No | `0` | Pagination offset. |
**Computed:** `private_locations` โ list of objects with `id`, `name`, `metadata`, `status`, `last_seen_at`, `monitor_count`, `created_at`, `updated_at`. Agent tokens are not returned by the list endpoint; use the singular data source to fetch one.
## Available Regions
Monitors can run from any of the following 28 regions:
**Fly.io:**`fly-ams`, `fly-arn`, `fly-bom`, `fly-cdg`, `fly-dfw`, `fly-ewr`, `fly-fra`, `fly-gru`, `fly-iad`, `fly-jnb`, `fly-lax`, `fly-lhr`, `fly-nrt`, `fly-ord`, `fly-sjc`, `fly-sin`, `fly-syd`, `fly-yyz`
**Koyeb:**`koyeb-fra`, `koyeb-par`, `koyeb-sfo`, `koyeb-sin`, `koyeb-tyo`, `koyeb-was`
**Railway:**`railway-us-west2`, `railway-us-east4`, `railway-europe-west4`, `railway-asia-southeast1`
## Full End-to-End Example
This example sets up a complete monitoring stack: HTTP and TCP monitors, Slack notifications, and a public status page with grouped components.
```terraformterraform { required_providers { openstatus = { source = "openstatusHQ/openstatus" version = "~> 0.1" } }}
provider "openstatus" { api_token = var.openstatus_api_token}
# --- Variables ---
variable "openstatus_api_token" { type = string sensitive = true}
variable "slack_webhook_url" { type = string sensitive = true}
# --- Monitors ---
resource "openstatus_http_monitor" "api" { name = "API Health" description = "Monitors the main API health endpoint." url = "https://api.example.com/health" periodicity = "5m" method = "GET" timeout = 30000 active = true public = true regions = ["fly-iad", "fly-ams", "fly-nrt"]
status_code_assertions { target = 200 comparator = "eq" }
body_assertions { target = "ok" comparator = "contains" }}
resource "openstatus_http_monitor" "website" { name = "Website" url = "https://www.example.com" periodicity = "1m" active = true public = true regions = ["fly-iad", "fly-ams", "fly-syd"]
status_code_assertions { target = 200 comparator = "eq" }}
resource "openstatus_tcp_monitor" "database" { name = "PostgreSQL" uri = "db.example.com:5432" periodicity = "1m" timeout = 10000 active = true regions = ["fly-iad"]}
resource "openstatus_dns_monitor" "domain" { name = "DNS Resolution" uri = "example.com" periodicity = "10m" active = true regions = ["fly-iad", "fly-ams"]
record_assertions { record = "A" comparator = "eq" target = "93.184.216.34" }}
# --- Notifications ---
resource "openstatus_notification" "slack" { name = "Slack Alerts" provider_type = "slack" monitor_ids = [ openstatus_http_monitor.api.id, openstatus_http_monitor.website.id, openstatus_tcp_monitor.database.id, ]
slack { webhook_url = var.slack_webhook_url }}
# --- Status Page ---
resource "openstatus_status_page" "main" { title = "Example Inc. Status" slug = "example-status" description = "Real-time status for all Example Inc. services." homepage_url = "https://example.com" contact_url = "https://example.com/support"}
resource "openstatus_status_page_component_group" "web" { page_id = openstatus_status_page.main.id name = "Web Services"}
resource "openstatus_status_page_component_group" "infra" { page_id = openstatus_status_page.main.id name = "Infrastructure"}
resource "openstatus_status_page_component" "api_component" { page_id = openstatus_status_page.main.id type = "monitor" monitor_id = openstatus_http_monitor.api.id name = "API" group_id = openstatus_status_page_component_group.web.id order = 1 group_order = 1}
resource "openstatus_status_page_component" "website_component" { page_id = openstatus_status_page.main.id type = "monitor" monitor_id = openstatus_http_monitor.website.id name = "Website" group_id = openstatus_status_page_component_group.web.id order = 1 group_order = 2}
resource "openstatus_status_page_component" "db_component" { page_id = openstatus_status_page.main.id type = "monitor" monitor_id = openstatus_tcp_monitor.database.id name = "Database" group_id = openstatus_status_page_component_group.infra.id order = 2 group_order = 1}```
## Related Resources
- **[HTTP Monitor Reference](/docs/reference/http-monitor)** โ Detailed specification for HTTP monitor configuration.- **[TCP Monitor Reference](/docs/reference/tcp-monitor)** โ Detailed specification for TCP monitor configuration.- **[DNS Monitor Reference](/docs/reference/dns-monitor)** โ Detailed specification for DNS monitor configuration.- **[CLI Reference](/docs/reference/cli-reference)** โ Manage monitors using the openstatus command-line interface.- **[Terraform Registry](https://registry.terraform.io/providers/openstatusHQ/openstatus/latest)** โ Official provider page with version history.- **[Provider Source Code](https://github.com/openstatusHQ/terraform-provider-openstatus)** โ GitHub repository for the Terraform provider.