The official Terraform provider for LastPing.
LastPing has an official Terraform provider, published on the public
Terraform Registry as
lastping-dev/lastping.
Declare your cron, CI/CD and AI-agent monitors as code, version them
alongside the jobs they watch, import the ones you already have, and let
an AI agent generate them. Six resources, one ephemeral resource, six
data sources. Free for individuals, with no monitor caps.
Install — three steps
A normal registry provider. Nothing to vendor, nothing to build. Terraform 1.5 or later; 1.10 or later if you want the ephemeral API key.
Declare the provider
Leave api_key out of the provider block on purpose:
the provider reads LASTPING_API_KEY from the
environment, so the credential never sits in a file you might
commit.
Authenticate
Create a key at app.lastping.dev → Settings → API Keys. The provider is scoped to the project that key belongs to — one key, one project, no ambiguity about what a plan is about to change.
Initialise and apply
terraform init downloads the provider from the public
registry and verifies its signature. From there it is an ordinary
Terraform workflow — plan, review, apply, and the monitoring exists.
A complete monitor, end to end
Monitor, destination, routing and alert wording — the whole chain in one file. This is not a fragment: it applies as-is against the real API.
terraform apply
creates five resources. The monitor's ping URL comes back as
ping_url
— feed it to whatever runs the job, and the loop is closed.
Export as Terraform — adopt, don't recreate
The usual reason teams never move monitoring into code is that they
already have monitors, and rewriting them by hand is a day nobody has.
So LastPing writes the HCL for you — and pairs every resource with an
import
block, so the first plan adopts what exists instead of proposing to
replace it.
Export the project
From the dashboard, or straight from the API with the same key Terraform uses:
Read what came out
Real output, unedited. Each import block tells
Terraform the resource already exists and gives it the id to adopt
— a monitor by its slug, a destination by UUID, a route by
<monitor-id>:<event-type>.
Fill in the secrets, then plan
The export cannot include credentials — the API never returns them
— so every secret attribute comes out as a
var. reference with a matching
sensitive = true variable block and a loud TODO. That
is deliberate: an empty string would silently ship a destination
that delivers nothing. Set the variables, then plan.
A clean plan is the whole point: your monitoring is now in version control and nothing about it changed.
The agent writes the monitoring in the same pull request
When a human builds a scheduled job, someone eventually files the "add monitoring" ticket. When an agent builds it, nobody does — the job ships and nothing watches it. The fix is not a better ticket process: it is making the monitoring part of the diff.
-
The provider's schema is public, so an agent can write correct HCL
Every resource, attribute and validation rule is documented on the Terraform Registry. An agent adding a nightly job to a repo can add the
lastping_monitorthat watches it in the same commit — and the reviewer sees both changes side by side, in one diff, instead of discovering six months later that the job has never been monitored. -
CI applies it, so the monitor cannot drift from the job
The same pipeline that deploys the job runs
terraform apply. Rename the job and you rename its monitor; delete the job and the monitor goes with it. There is no state in which a monitor sits green because the thing it was watching stopped existing. -
Agents that would rather act than write files use MCP
Terraform is the right tool when monitoring belongs in a reviewed, versioned repo. When an agent needs to create a monitor for itself right now — mid-conversation, with no PR — the LastPing MCP server exposes the same capabilities as tool calls. Both paths reach the same API and the same monitors;
Export as Terraformis how a monitor created over MCP later becomes code.
The concept, at length, on its own page: what monitoring as code means and why it matters more with agents.
A credential that does not outlive the run
The uncomfortable question about any provider is where its key ends up.
The ephemeral lastping_api_key
has a good answer: nowhere.
Terraform refuses to place an ephemeral value anywhere that persists, so
the key cannot end up in state, in an output, or in a resource argument
even by accident. The ttl
is the safety net: if a run is killed before it can revoke its key, the
key still expires on its own server-side. Set it to comfortably exceed
your longest apply — LastPing has no endpoint to extend a key, so one
cannot be renewed in place.
The managed
lastping_api_key
resource still exists for credentials that must outlive the run — a CI
job, a container. Its plaintext lands in state, which the provider
documentation says plainly rather than burying.
Resource reference
Six managed resources, one ephemeral resource, six data sources. Every row links to its page on the Terraform Registry.
| Resource | What it manages |
|---|---|
| lastping_monitor | A heartbeat, CI or HTTP probe monitor. Cron or simple-interval schedule, tags, runaway ceiling, pause state. Creating a monitor whose slug already exists fails loudly rather than taking it over silently — import it instead. |
| lastping_destination | Where alerts are delivered: Slack, email, custom webhook, Telegram, Discord, ntfy, Pushover, Microsoft Teams, Google Chat. Credentials are write-only — stored, never returned. |
| lastping_route | One monitor's alerts for one event type (down, recovery, fail) routed to a list of destinations. One resource per event type; an empty list mutes that event without deleting the route. |
| lastping_alert_template | Custom alert message bodies for one monitor, overriding the built-in wording. One resource owns the monitor's whole template map, because the API replaces the set rather than merging into it. |
| lastping_status_page | A public or private status page over a chosen set of monitors. Public slugs are globally unique across every LastPing account — see the note below. |
| lastping_api_key | A long-lived API key for automation that outlives the run. The plaintext is stored in Terraform state; prefer the ephemeral resource below when you can. |
| ephemeral lastping_api_key | A short-lived key minted for one run and revoked when it ends. Never written to plan or state. Requires Terraform 1.10 or later. |
| data lastping_project | The project the configured key belongs to. Doubles as a credential smoke-test: a revoked key fails here at plan time rather than partway through an apply. |
| data lastping_monitors | Every monitor in the project, optionally filtered by tag. Useful for building a status page from a tag instead of a hand-maintained list of ids, and for auditing monitors created outside Terraform. |
| data lastping_monitor | A single monitor by id or slug — how you attach a route to a monitor Terraform does not manage, without importing it. |
| data lastping_destination | A single destination by id or name. Reports only the non-secret target hint; a name matching more than one destination is an error, not an arbitrary pick. |
| data lastping_incidents | One monitor's incident history, newest first. For outputs and reports — incident history moves without Terraform doing anything, so do not feed it into a managed resource. |
| data lastping_metrics | The project's monitors as Prometheus gauges, exactly as the metrics endpoint returns them. For writing a scrape snapshot to disk or feeding a dashboard module. |
Four things worth knowing before your first apply
The provider documentation covers all of these, but these are the ones that actually cost people an afternoon.
Alert templates use {token}, not Go templates
The placeholders are {check_name},
{status}, {event}, {cause},
{last_ping}, {schedule},
{incident_url}, {run_url},
{branch}, {commit}, {actor},
{failing_stage}, {duration},
{latency}, {status_code} and
{url}.
A body containing {{.CheckName}} is accepted — it does
not match the token pattern, so validation has nothing to object to
— and then renders literally into a real alert at 3am. An
unrecognised token in {token} shape, such as
{check_nam}, is rejected at apply time and names the
offending key. The trap is the syntax that looks like a template
engine and is not one.
grace_s is required
Omit it and the API returns 400 — grace 0s outside [60,
31536000]. There is no default, deliberately: how long a job
may be late before it counts as missing is a decision about that
job, not something a monitoring tool should guess.
The exception is monitor_type = "http", where the
server floors the effective grace at 2 × probe_interval_s
so one slow probe cannot false-fire. Set grace_s there
only to ask for more than the floor; a smaller value is
rejected at plan time rather than being silently raised.
Status page slugs are global
Unusually, a status page slug is unique across every LastPing account, not scoped to your project — a public URL can only belong to one page anywhere. So a slug you have never seen may already be taken by a stranger, and a configuration that applied cleanly yesterday can fail to recreate today for that reason alone.
Because slug forces replacement and Terraform destroys
before creating by default, renaming a public page releases its slug
into that global namespace before claiming the new one. Add
lifecycle { create_before_destroy = true } to public
status pages.
Terraform will not adopt what it did not create
Routes and alert templates are both whole-set writes: one
PUT replaces everything. So creating either on a monitor
that already has them configured — through the dashboard, or over
MCP — would silently overwrite someone else's alerting, with the next
incident as the discovery channel.
The provider refuses instead, and tells you to
terraform import them. That is the safe failure, and it
is why Export as Terraform emits
import blocks rather than plain resources.
One deliberate gap: binding a monitor to a CI provider is not manageable through Terraform. Doing so mints a write-once secret the API returns only at creation and can never read back, so the provider does not model it rather than pretending to. Configure CI binding in the dashboard — the export marks any monitor where this applies with a comment explaining why the attributes are missing.
Questions
Front-loaded answers — the most important fact first.
-
Does LastPing have a Terraform provider?
Yes. The official provider is published on the public Terraform Registry as
lastping-dev/lastping. Addsource = "lastping-dev/lastping"andversion = "~> 0.1"to yourrequired_providersblock andterraform initdownloads and signature-verifies it like any other registry provider. It covers six managed resources, one ephemeral resource and six data sources, and needs Terraform 1.5 or later — 1.10 or later if you use the ephemeral API key. -
Can I import monitors I already created in the dashboard?
Yes, and you do not have to write the HCL yourself. Export as Terraform renders your existing monitors, destinations, routes, alert templates and status pages as HCL, and pairs every resource with a Terraform
importblock — so the first plan adopts what you already have rather than proposing to recreate it. Secrets are the one thing it cannot include: the API never returns them, so each secret attribute is emitted as avar.reference with a matchingsensitivevariable block for you to fill in. -
Is the LastPing Terraform provider free?
Yes. LastPing is free for individuals — no monitor cap, no feature gate — and the Terraform provider is part of that. The provider itself is open source (MPL-2.0, source on GitHub) and adds no cost of its own. The one free-tier limit that shows up in Terraform is status pages: one public status page per project, with private pages unlimited.
-
Which LastPing resources can Terraform manage?
Six managed resources —
lastping_monitor,lastping_destination,lastping_route,lastping_alert_template,lastping_status_pageandlastping_api_key— plus an ephemerallastping_api_keyand six data sources. See the resource reference for the full list.The deliberate gap is binding a monitor to a CI provider: that mints a write-once secret the API returns only at creation and can never read back, so the provider does not model it. Configure CI binding in the dashboard; everything else is declarable.
-
Can an AI agent write the Terraform for me?
Yes, and this is the intended path. The provider's schema and documentation are public on the Terraform Registry, so a coding agent can write correct HCL for a monitor in the same pull request that adds the job it watches — no separate ticket, no dashboard visit, and the reviewer sees both changes together.
Agents that prefer to act on the live API rather than write files can use the LastPing MCP server instead. Both paths reach the same monitors, and Export as Terraform is how one created over MCP later becomes code.
-
How do I keep a LastPing API key out of Terraform state?
Use the ephemeral
lastping_api_key, which requires Terraform 1.10 or later. It mints a key for the duration of the run, hands it to a provider configuration, and revokes it when the run ends — nothing about it is written to plan or state. The key also carries a server-side expiry as a safety net, so a run that is killed before it can revoke its key still leaves a credential that stops working on its own. -
Can I use the provider against a self-hosted LastPing?
Yes. Set
LASTPING_ENDPOINTin the environment, or theendpointargument on the provider block. It defaults tohttps://app.lastping.dev.
Put your monitoring in the same repo as the jobs it watches.
Get a free API key, add one required_providers block, and
declare your first monitor. Already have monitors? Export them as
Terraform and adopt them with a clean plan.