Submit an issue View all issues Source
MIR-837

PostgreSQL addon: production readiness gaps from RFC 0059 review

Done public
evan evan Opened Mar 18, 2026 Updated Mar 26, 2026

Context

Review of the PostgreSQL addon implementation against RFC 0059 identified several gaps that need to be addressed before production release. The core framework, entity schemas, provider interface, saga-based provisioning, and CLI are all solid. The simplified variant names (small/shared instead of small-local/shared) are intentional.

Tasks

1. Add controller-level compensation for failed provisioning

File: controllers/addon/controller.go

If provider.Provision() succeeds but a subsequent step fails (e.g., env var injection, setting active version), the controller sets status: error but never calls provider.Deprovision() to clean up. This leaves orphaned PostgresServer entities, sandbox pools, and databases.

The RFC specifies a ProvisionAddonSaga where step 2 (provider.Provision()) has compensate: Call provider.Deprovision(). Either wrap the controller's provision flow in a saga or add explicit cleanup on failure after a successful Provision() call.

2. Implement app.toml addon removal reconciliation

Files: servers/build/build.go (provisionAddons)

Currently provisionAddons() only creates new addon associations from app.toml — it never detects addons that were removed from app.toml and deprovisions them. The RFC states: "addons removed from the file are detached."

The fix should:

  • List existing addon associations for the app
  • Compare against the addons declared in app.toml
  • Call DeleteInstance for any associations whose addon is no longer in app.toml

3. Add LocalityMode to the provider interface

Files: pkg/addon/provider.go, pkg/addon/postgresql/provider.go

The RFC defines LocalityMode() LocalityMode on AddonProvider with values OnCluster and Remote. This is exposed to users so they understand whether an addon runs locally or depends on external services. The value should be stored on the Addon entity at registration time.

4. Harden deprovision env var removal

File: controllers/addon/controller.go (deprovision)

When removeEnvVars() fails during deprovisioning, the controller logs a warning and proceeds to delete the association entity. This can leave stale env vars (e.g., DATABASE_URL pointing at a deleted database) on the app. The failure should either block the deprovision (so the controller retries) or be retried before deleting the association.

5. Add medium and large dedicated variants

File: pkg/addon/postgresql/plans.go

Only small (1 GB) and shared exist. Production users need larger dedicated options. Add:

  • medium: ~10 GB storage
  • large: ~50 GB storage

Include appropriate display details (storage size) in the variant definitions.