Configuration as code
Manage a project's configuration from files with wtctl, or from Terraform. Both use the same kinds and the same identity key: metadata.name, per kind, per project.
Manifests
apiVersion: watchtower.dev/v1
kind: Monitor
metadata:
name: api-health
spec:
env_id: env_1
kind: http
interval_s: 60
config: { url: https://example.com/health }spec is the API request body of the kind without its name. Several documents can share a file (---).
Kind | API collection | Name field | Notes |
|---|---|---|---|
|
|
| |
|
|
| Prometheus group body. The API cannot list groups, so every apply sends it and the server reports "unchanged". |
|
| n/a | One tree per project. The spec is the tree. It cannot be deleted or pruned. |
|
|
|
|
|
|
| |
|
|
| |
|
|
| A silence has no name, so its comment is its identity. |
|
|
| |
|
|
| |
|
|
|
|
|
|
| |
|
|
| |
|
|
| |
|
|
| |
|
|
| |
|
|
| Not pruned: services are also discovered from telemetry. |
|
|
| |
|
|
|
|
|
|
| Created once. The token is printed once on stderr (and kept as the sensitive |
Commands
wtctl apply -f <dir|file> --project <id> [--dry-run] [--prune]
wtctl diff -f <dir|file> --project <id> [--prune] # exit 1 when anything differs
wtctl export --project <id> [--kinds AlertRule,Monitor] [--out <dir>]
wtctl completion bash|zsh|fish|powershell--api and --key default to $WT_API and $WT_API_KEY; --project to $WT_PROJECT.
applycreates what is missing and updates what differs. A second apply with unchanged files changes nothing. Only the fields a manifest names are compared, so server-side defaults never show as changes.--prunealso deletes live resources of the kinds present in the files that no manifest names. Without it nothing is ever deleted.exportwrites manifests to stdout (or one file per resource below--out) thatapplyaccepts unchanged.
Secrets
Secret fields (Receiver.secrets.*, CheckSecret.value) accept only ${ENV} references. A literal value is rejected before anything is sent, and an unset variable is an error. export writes references such as ${WT_CHECKSECRET_API_TOKEN_VALUE}, never values.
Terraform
provider "watchtower" {
endpoint = "https://watchtower.example.com" # or $WT_API
api_key = var.api_key # or $WT_API_KEY
project = "prj_..." # default project, or $WT_PROJECT
}
resource "watchtower_monitor" "api" {
name = "api-health"
spec = jsonencode({ env_id = "env_1", kind = "http", interval_s = 60, config = { url = "https://example.com/health" } })
}Every kind is a resource named watchtower_<snake_case_kind> with project (optional), name and spec. Import by name: terraform import watchtower_monitor.api prj_.../api-health (or just api-health with a default project). Drift in fields named by spec shows as a changed spec.
Generated client
go/wtapi is generated from apps/web/openapi.json (go generate ./wtapi: a small preprocessor lowers OpenAPI 3.1 to 3.0 and keeps the config-resource paths, then a pinned oapi-codegen runs). wtctl and the provider use its server URL, auth hook and transport.
Phase 6 resources
watchtower_attribute_registry (name = attribute key, spec carries signal), watchtower_archive_config (name = signal; credentials take ${ENV} references only, never read back) and watchtower_fleet_config (create-only; destroy only forgets it, there is no DELETE route), watchtower_retention_rule (name = the rule's priority, spec carries signal, days, match), watchtower_change_source (name = provider kind; the one-time secret lands in the sensitive token attribute and is never read back; no in-place update) and the org-scoped watchtower_ip_allowlist (name = scope org|api_keys|ingest|sessions; destroy resets it to disabled), watchtower_org_sso (singleton) and watchtower_secret_store (credential takes ${ENV} references only, never read back; replace to change). For org-scoped resources the project attribute holds the org id; the provider takes a default org (or $WT_ORG); import with <org>/<name>. Uncovered families and reasons: go/terraform/resources/coverage_exempt.txt.
Provider docs and releases
make tf-docs regenerates go/terraform/docs/ with tfplugindocs (MPL-2.0). scripts/release-provider.sh <version> builds terraform-provider-watchtower_<version>_<os>_<arch>.zip for each target, writes SHA256SUMS and signs it with $WT_GPG_KEY.