CapyDB Docs
Reference

Terraform provider

The capy-base/capydb provider for Terraform and OpenTofu — projects, preview databases, API keys, and webhook endpoints as code.

What it is

The official Terraform/OpenTofu provider for CapyDB, built on terraform-plugin-framework (protocol v6; Terraform ≥ 1.0 and OpenTofu). It manages the control-plane surface — it does not manage what is inside your database; that stays plain SQL and migrations.

Provider configuration

terraform {
  required_providers {
    capydb = {
      source  = "capy-base/capydb"
      version = "~> 0.1"
    }
  }
}

provider "capydb" {
  api_key = var.capydb_api_key # sensitive; falls back to CAPYDB_API_KEY
  # api_url falls back to CAPYDB_API_URL, then https://capydb.dev/api/capydb
}

The API key is an organization key (capy_live_...). The provider's operations need these scopes: projects:read/projects:write (projects, previews), credentials:read (the connection data source), and jobs:read (waiting on async jobs).

Resources and data sources

ResourcePurpose
capydb_projectA managed logical Postgres database. Async provision/delete; environment updatable in place; importable by id.
capydb_preview_databaseDisposable preview/branch database with a TTL. Raising ttl_hours extends in place; lowering forces replacement.
capydb_api_keyOrg (or project-scoped) API key. Plaintext captured once into the sensitive token attribute; delete revokes.
capydb_webhook_endpointOutbound webhook receiver. Bump secret_version to rotate the HMAC signing secret in place.
Data sourcePurpose
capydb_clustersActive regions projects can be placed on.
capydb_projectLook up a project by id or slug (exactly one).
capydb_project_connectionPooled/direct connection URLs with credentials embedded (sensitive).
capydb_organizationThe org behind the configured key, including billing plan/status.

Quickstart

resource "capydb_project" "app" {
  name        = "my-app"
  environment = "production"
}

# Ephemeral clone of the production database for a pull request.
resource "capydb_preview_database" "pr" {
  project_id = capydb_project.app.id
  name       = "pr-42"
  mode       = "clone"
  ttl_hours  = 48
}

data "capydb_project_connection" "app" {
  project_id = capydb_project.app.id
}

output "database_url" {
  value     = data.capydb_project_connection.app.pooled_url
  sensitive = true
}

Asynchronous jobs and timeouts

Project provision/delete and preview create/delete are asynchronous jobs. The provider enqueues the job and polls /v1/jobs/{id} every 5 seconds until it reaches completed or failed, bounded by the resource's timeouts attribute (create/delete, both defaulting to 20 minutes):

resource "capydb_project" "app" {
  name = "my-app"

  timeouts = {
    create = "30m"
    delete = "30m"
  }
}

On create, the resource id is written to state before waiting, so a timed-out or failed job never orphans the project or preview — re-run terraform apply or inspect the job in the dashboard.

Secrets land in state

capydb_api_key.token, capydb_webhook_endpoint.signing_secret, and the capydb_project_connection URLs are sensitive values — the first two are returned exactly once by the API, and the connection URLs embed live credentials. All of them are persisted in Terraform state. Treat the state file accordingly: encrypted remote backend, restricted access. If state leaks, rotate.

A practical note on empty lists

CapyDB list endpoints may serialize empty lists as JSON null. The provider normalizes every list it reads to an empty, non-null list, so length(data.capydb_clusters.available.clusters) and friends are always safe.