Skip to content

Email with Terraform

Declare domains, send keys, webhooks, and inbound routes as code with the longbridge_email_* resources — a small example wiring all four, and a note on the reveal-once secrets that land in state.

The Longbridge provider manages Email resources declaratively on Terraform or OpenTofu, alongside the rest of your Longbridge infrastructure. This page covers the Email-specific resources; for install, authentication, and how to handle state and secrets in general, start with the provider introduction.

Early access. Email is being rolled out behind an Org flag. If you don’t see it in the Console, it isn’t enabled for your organization yet.

The resources

ResourceManages
longbridge_email_domainA sending and/or receiving domain, and its DNS records.
longbridge_email_send_keyA data-plane send key (also the SMTP password).
longbridge_email_webhookAn HMAC-signed webhook endpoint.
longbridge_email_routeAn inbound route from a domain pattern to a webhook.

An example

This registers a send-only root domain and a receive-armed subdomain, mints a send key scoped to the root, creates a webhook, and routes support@ inbound mail to it:

# Send from the root domain (additive DKIM — coexists with existing mail).
resource "longbridge_email_domain" "main" {
  name = "example.com"
}

# Receive on a dedicated subdomain (arm_receive is an EXCLUSIVE MX takeover —
# never set it on a domain that already has mailboxes).
resource "longbridge_email_domain" "inbound" {
  name        = "in.example.com"
  arm_receive = true
}

# A send key restricted to the root domain.
resource "longbridge_email_send_key" "app" {
  name       = "production api"
  domain_ids = [longbridge_email_domain.main.id]
}

# Where events and inbound mail are delivered.
resource "longbridge_email_webhook" "app" {
  url         = "https://app.example.com/hooks/email"
  event_types = ["email.delivered", "email.bounced", "email.received"]
}

# Route support@in.example.com to the webhook as email.received.
resource "longbridge_email_route" "support" {
  domain_id   = longbridge_email_domain.inbound.id
  pattern     = "support"
  endpoint_id = longbridge_email_webhook.app.id
}

After terraform apply, read the DNS records to publish from the domain resource’s dns_records, and the domains’ send_state / receive_state to watch verification. The pattern is the local part — exact, a prefix-* trailing star, or * for catch-all — the same routing rules as everywhere else.

Secrets land in state

Two Email resources hold reveal-once secrets that the API returns only at creation, so the provider keeps them in state to stay useful across runs:

  • longbridge_email_send_key.secret — the lpk_<id>.<secret> sending credential.
  • longbridge_email_webhook.signing_secret — the whsec_… HMAC secret.

Warning: These land in your state file. Treat state as a secret: use a backend with encryption (OpenTofu’s native state encryption, or your backend’s), and never commit it. On import, both secrets come back blank because they’re unrecoverable — rotate to obtain a fresh, usable value.

Rotate with no downtime

Both secret-bearing resources take a rotation_triggers map. Change any value in it to force a replacement that mints a fresh secret; pair it with create_before_destroy so the new credential exists before the old one is destroyed — the zero-gap rotation done declaratively:

resource "longbridge_email_send_key" "app" {
  name       = "production api"
  domain_ids = [longbridge_email_domain.main.id]

  rotation_triggers = {
    rotated = "2026-07-01"  # bump to rotate
  }

  lifecycle {
    create_before_destroy = true
  }
}

The canonical reference

Every resource, argument, and attribute is documented on the registries, generated from the provider schema and versioned with each release:

Where to next

  • Provider introduction — install, authenticate, handle state.
  • Send keys — the credential model behind the rotation above.
  • Webhooks — verifying the signature on what these endpoints receive.