In the upcoming Crossplane v1.11.0, we are announcing the beta release of the CompositionRevision feature. It provides a way to track changes to Compositions and create Composite Resources (XRs) with different revisions. It was introduced as an alpha feature in v1.4.0 and has been under active use by the community since then. Please have a look at the design document and the guide for more details. We are excited to announce that we have reached a milestone and look forward to hearing your feedback.
While promoting this feature to beta, we fixed several bugs and made some changes to the behavior of the feature, like how we decided to create a new CompositionRevision or what happens when we roll back to a previous one. This blog post will explain the differences and how they improve the experience of using CompositionRevisions.
What is CompositionRevision, and how is it used?
A Composition is a mutable resource that can be updated over time, whereas CompositionRevision is a snapshot of a Composition at a particular time. This means there is a one-to-many relationship between Compositions and CompositionRevisions. When we create an XR, we can specify which CompositionRevision to use with the
compositionRef field. If the
compositionRef is not specified, the controller automatically sets the latest revision of the Composition.
The CompositionRevision used by an XR can be updated automatically. This is controlled by the
compositionUpdatePolicy field of the XR, which is set to
Automatic by default. In this case, whenever a CompositionRevision is created, the XR is updated to use the latest revision. If we want to disable this behavior, we can set the
How are CompositionRevisions created?
CompositionRevisions are created automatically when a Composition is created or updated. To decide whether to create a new revision or roll back to a previous one, the composition controller calculates the hash of the Composition and compares it with the hashes of previous revisions. If the hash is different, a new revision is created. If the hash is the same as one of the existing revisions, the Composition is rolled back to that revision, and the revision number is incremented.
During the alpha release, only the Composition spec was included in the hash calculation. Now, we start to include the Composition labels and annotations. This change makes it possible to have two different revisions of the same Composition without a spec update. We also started to propagate Composition labels to CompositionRevisions during creation time. Together with these two changes, we can utilize a new feature called CompositionRevision Selectors.
One of the most significant changes in this release is the introduction of the
CompositionRevisionSelector field to XR spec. This field can be used with
CompositionUpdatePolicy: Automatic to enable channel-based deployments. When this field is set, the XR will be created with the latest Composition revision that matches the selector. This is useful when we want to deploy the latest revision of a Composition to a particular environment. For example, we can update the Composition's spec with the
channel: staging label and do some sanity checks. After successful testing, we can update the label to
channel: prod and deploy the latest revision to production.
How to use CompositionRevisions
As a beta feature, CompositionRevisions are enabled by default unless they are disabled by the
--enable-composition-revisions=false flag. It is not recommended to interact with CompositionRevisions directly, and all changes should be done on Compositions, including marking a specific composition state with a label.
In the following example, we have a Composition that provisions a Kubernetes cluster. Our Platform Engineer maintains two different release channels for application developers, rapid and stable. The rapid channel is updated with the latest k8s version, whereas the stable channel is updated less frequently and is used in production environments. To achieve this, we switch between the
channel: rapid and
channel: stable labels while updating the
on the Composition. Since the Crossplane pod propagates the labels from Composition to CompositionRevision during creation, we can use this label to select the desired channel.
When Application Developers want to create a Kubernetes cluster to test a new feature, they can create an XR with
channel: rapid and test it with the latest k8s version. At the same time, they can create an XR with a
channel: stable label to reproduce a bug in production. A CompositionRevision will be chosen based on the label selector in the XR spec. If the selector is not set, the latest revision, which is indicated by the largest revision number, will be used. The application developer creates two XRs with different
matchLabels in the following example. Therefore, we end up having two different Kubernetes clusters with different k8s versions.
When a new k8s patch version is released, the Platform Engineer can update the Composition with the
channel: rapid label. Once this change is done, the XR with
channel: rapid will be updated automatically to use the new k8s version, whereas the XR with
channel: stable will continue to use the stable version.
We are excited to announce the beta release of CompositionRevisions. This feature will help users to manage their Compositions and XRs safely and reliably. There is a tutorial with example manifests showing how to use CompositionRevisions in the Crossplane docs, which installs the latest version of Crossplane with the following commands:
kubectl create namespace crossplane-system helm repo add crossplane-master https://charts.crossplane.io/master/ helm repo update helm install crossplane -n crossplane-system crossplane-master/crossplane --devel --version 1.11.0-rc.0.101.gc4fb2315
We would love to hear your feedback on this feature. Please feel free to play with it, and let us know if you have any feedback or questions. You can reach us via Slack.