A database is part of the environment, not a footnote
Backing services as first-class objects — how they are declared, why they move by release rather than by commit, and the two ways they bite.
A Resource is a backing service the platform provisions: a Postgres, an object
store, a Zulip bot identity, a whole Helm chart. It is declared once and bound
per environment, exactly like a component — and it is deployed estate, not
configuration.
Components and resources together, because that is what an environment is.
Everything in one cell →It moves by release, not by commit
A component has a commit, because something built it. A resource does not — it
moves by ResourceRelease, which is the identity a resource actually has.
That is why a resource row shows a release where a component shows
component@sha. Rendering a database through the component columns gives an
empty Commit, a dash for Built by, and "internal" for an endpoint it does not
have: none of those is false on its own, and together they describe the wrong
kind of thing.
Each release diffed against the one before it.
A resource's release history →Two ways this bites
resourceRelease must be pinned explicitly — it is not resolved to "latest",
and a binding without one refuses with spec.resourceRelease is unset.
So editing a resource type does not roll anything. The pins in
apps/*/openchoreo/bindings-*.yaml have to be advanced by hand, and until they
are, the cluster is running the old definition while the repository describes a
new one. Sixteen ResourceReleases for Zulip alone have drifted this way.
A resource binding set to Retain survives the deletion of the thing that owns
it. That sounds safe and is: a terminating resource breaks dependency
resolution for everything that binds it, so the symptom shows up on a
component that was never touched.
Review environments set Delete deliberately — a pull request's database should
not outlive the pull request.
An environment can be nothing but resources
chat owns Zulip through a Helm chart resource and declares no components at
all. A board built from component rows alone reported "nothing is bound in any
environment yet" about an environment with a running Zulip in it.
Which is the general shape of the mistake worth avoiding here: treating backing services as configuration attached to a component, rather than as things that are deployed, versioned, and capable of being the only occupant of an environment.