PostgreSQL addon: production readiness gaps from RFC 0059 review
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
DeleteInstancefor 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 storagelarge: ~50 GB storage
Include appropriate display details (storage size) in the variant definitions.