ResourceRelease
A ResourceRelease is an immutable snapshot of a Resource and the referenced ResourceType or ClusterResourceType at the moment it was cut. ResourceReleases ensure reproducibility and enable reliable rollback by preserving the exact state used to render the binding for each environment.
ResourceReleases are created exclusively by the Resource controller. When the hash of Resource.spec plus the referenced ResourceType's spec changes, a new ResourceRelease is cut with the name {resource}-{hash}. They are deleted by the Resource finalizer when the parent Resource is torn down.
API Versionβ
openchoreo.dev/v1alpha1
Resource Definitionβ
Metadataβ
ResourceReleases are namespace-scoped resources created in the same namespace as the Resource.
apiVersion: openchoreo.dev/v1alpha1
kind: ResourceRelease
metadata:
name: <resource-name>-<hash>
namespace: <namespace>
The name shape mirrors the ComponentRelease pattern: a stable prefix derived from the Resource name plus a content-addressed hash discriminator. Two ResourceReleases for the same Resource can therefore coexist during a rolling promotion.
Spec Fieldsβ
The entire spec is immutable after creation. Edits are rejected by a CEL validation rule on the CRD.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
owner | ResourceReleaseOwner | Yes | - | Identifies the Resource and project this snapshot belongs to |
resourceType | ResourceReleaseResourceType | Yes | - | Frozen snapshot of the (Cluster)ResourceType resource at release time |
parameters | object | No | - | Frozen snapshot of Resource.spec.parameters at release time |
ResourceReleaseOwnerβ
| Field | Type | Required | Description |
|---|---|---|---|
projectName | string | Yes | Name of the project that owns this Resource (min: 1) |
resourceName | string | Yes | Name of the Resource this release belongs to (min: 1) |
ResourceReleaseResourceTypeβ
Captures both the identity (Kind + Name) and the full spec of the referenced (Cluster)ResourceType at release time, so a namespace-scoped ResourceType and a cluster-scoped ClusterResourceType with the same name can coexist in the snapshot history.
| Field | Type | Required | Description |
|---|---|---|---|
kind | string | Yes | Either ResourceType (namespace-scoped) or ClusterResourceType (cluster-scoped) |
name | string | Yes | Name of the (Cluster)ResourceType resource (min: 1) |
spec | ResourceTypeSpec | Yes | Frozen specification of the (Cluster)ResourceType |
ClusterResourceType snapshots currently share the namespaced ResourceType spec shape; if ClusterResourceType later gains cluster-only fields, snapshots taken from a ClusterResourceType source will not preserve themβmirrors the ComponentRelease precedent.
Status Fieldsβ
ResourceRelease currently has no status fields. Observed deployment state (per-environment readiness, output resolution, finalization) lives on the ResourceReleaseBinding that pins this snapshot.
Examplesβ
Basic ResourceReleaseβ
A snapshot cut by the Resource controller after a developer creates a Resource referencing the postgres ClusterResourceType.
apiVersion: openchoreo.dev/v1alpha1
kind: ResourceRelease
metadata:
name: doclet-postgres-abc12345
namespace: default
spec:
owner:
projectName: doclet
resourceName: doclet-postgres
resourceType:
kind: ClusterResourceType
name: postgres
spec:
parameters:
openAPIV3Schema:
type: object
properties:
database:
type: string
default: postgres
environmentConfigs:
openAPIV3Schema:
type: object
properties:
storage:
type: string
default: "10Gi"
retainPolicy: Retain
outputs:
- name: host
value: "${metadata.name}.${metadata.namespace}.svc.cluster.local"
- name: port
value: "5432"
- name: password
secretKeyRef:
name: "${metadata.name}-creds"
key: password
resources:
- id: password-secret
template:
# ... ExternalSecret or Password generator manifest ...
- id: statefulset
readyWhen: "${applied.statefulset.status.readyReplicas == 1}"
template:
# ... Postgres StatefulSet ...
parameters:
database: doclet
ResourceRelease From a Namespace-Scoped ResourceTypeβ
apiVersion: openchoreo.dev/v1alpha1
kind: ResourceRelease
metadata:
name: order-cache-def67890
namespace: default
spec:
owner:
projectName: order-service
resourceName: order-cache
resourceType:
kind: ResourceType
name: valkey-cache
spec:
# ... frozen ResourceType spec at release time ...
parameters:
version: "8"
Immutabilityβ
ResourceRelease's spec is enforced immutable by a CEL validation rule (self == oldSelf). All fieldsβowner, resourceType, parametersβare part of the snapshot guarantee:
- Spec edits via
kubectl editor API PATCH are rejected. - The Resource controller cuts a new ResourceRelease (new hash, new name) when either the Resource spec or the referenced (Cluster)ResourceType spec changes. The previous snapshot is left untouched until the Resource finalizer GC's it.
Lifecycleβ
- Create. Resource controller computes the hash of
Resource.spec + (Cluster)ResourceType.spec. If no ResourceRelease with that hash exists, it creates one named{resource}-{hash}and updatesResource.status.latestRelease. - Promote. A platform engineer or GitOps process updates a
ResourceReleaseBinding.spec.resourceReleaseto point at this snapshot. The binding controller renders the snapshot'sresourceType.specwith the snapshot'sparametersand the binding'sresourceTypeEnvironmentConfigs, then applies the resulting manifests to the data plane. - Delete. When the parent Resource is deleted, the Resource finalizer's second phase removes all owned ResourceReleases (matched by
spec.owner.resourceName). Directkubectl delete resourcerelease ...is not blocked by a finalizer but breaks the binding chain if any binding still references the snapshot.
Related Resourcesβ
- Resource β Owns this snapshot through
spec.owner.{projectName, resourceName} - ResourceType β Source template captured in
spec.resourceType.spec - ClusterResourceType β Cluster-scoped variant of the source template
- ResourceReleaseBinding β Pins this snapshot to a specific environment
- RenderedRelease β Final manifests produced by the binding controller
- ComponentRelease β Component-side counterpart