I’ve covered Composite Resources (XRs) and Compositions in previous posts. I’ll provide a brief summary here, but you can review them in more detail if needed.. In the next series of posts, I’ll cover how we use Composition patches to pass values between/to related resources (all patch methods are documented here).
It is important to keep the concepts of Composite Resource and Composition clearly separated in your understanding. A Composite Resource (XR) defines a custom API, exposed via kube-apiserver. It selects a Composition that composes it into a collection of Managed Resources . The Composition is simply a ‘recipe’ to compose the Composite Resource(s). We patch to, from, and within Composite Resources via a Composition. We do not patch Compositions.
Beginning with a Composite Resource Definition (XRD), we see the definition of a new kube-apiserver CRD type (XEKS) at path aws.platformref.upbound.io.
Note: You can find a link to the repo containing the full platform reference configuration here.
Within this XRD, we see the schema defines (among others) fields for spec.parameters.nodes.count and spec.parameters.nodes.size. When applied, this XRD creates a new custom resource type in your cluster referred to as an XR (Composite Resource).
Below we see an instance of the XR being defined. When this XR instance is created, it selects a Composition. This can be one we assign (multi-cloud for example when we want to have a single XR that can provision managed K8s clusters to multiple clouds), or it can be a default Composition that is selected automatically.
Below, we see part of the selected Composition. In this part, we are creating a Managed Resource of type NodeGroup from the eks.aws.upbound.io Provider aws api path. The default patch method is FromCompositeFieldPath. If no type is specified (as below), this patch method is applied. With FromCompositeFieldPath, we take a value from the XR and supply it to the Resource Template.
The values supplied in the node size and count fields of the XR being patched into the NodeGroup Resource Template. We can find the NodeGroup (and all other resources) documented here.
Note: While the desiredSize and instanceTypes are defined with values of ‘1’ and ‘t3.medium’, they will be set from the values we supplied in the XR instance via the patches
The patches use the yaml array ([0]) syntax because they are patching to an array field. The instanceTypes is additionally using a transform of type ‘map’. Transforms enable us to manipulate supplied values. In this case, we are mapping the XR enum of ‘small, medium, large’ to specific aws instance types. This is handy in a multi-cloud scenario where we need to convert something like ‘small’ to a cloud provider specific instance type value. All transform types are covered in the Composition documentation I linked above.
This has covered the basic FromCompositeFieldPath patch with a simple use case of passing supplied values from an XR instance. In the next post, I’ll cover ToCompositeFieldPath where we will see how to pass values from one resource to another.