Crossplane: A Package-Based Approach to Platform Building
What if onboarding a new software vendor was as easy as adding a dependency?
Jan 17th, 2023 12:01pm by
Upbound sponsored this post.
Crossplane Packages and API Dependencies
Crossplane is a framework for building control planes. Large cloud providers offer a suite of services that provide varying levels of abstraction over physical compute. To build the platform that can offer these services to thousands of customers, cloud providers have an underlying control plane that ensures the desired state of infrastructure that a customer has requested is aligned with the actual state. If they are not already, the control plane will work to drive the two states to alignment. In simplest terms, the control plane is what translates from the interface exposed to users to actions required to satisfy their requests. A platform is the API that the control plane exposes.
In Crossplane, the interface, or APIs, as well as the translation logic is grouped into packages. Packages that include both APIs and logic are referred to as Providers, while those that strictly translate from an abstract interface to a more granular one are referred to as Configurations.
Much like libraries in a programming language, packages may declare dependencies on other packages and build upon their APIs. When a package is installed in a Kubernetes cluster where Crossplane is running, the package manager will evaluate its dependencies and install compatible versions of any that are not already present.
apiVersion: meta.pkg.crossplane.io/v1
kind: Configuration
metadata:
name: my-org-infra
spec:
crossplane:
version: ">=v1.0.0"
dependsOn:
- provider: xpkg.upbound.io/upbound/provider-aws
version: ">=v0.23.0"
Defining a Platform with a Root Package
While Crossplane allows users to install many packages alongside one another, a common pattern has emerged of defining a single “root” package, which is an ancestor node of every other package that gets installed in a control plane. Doing so makes the entire API surface area reproducible by installing that one package. As an organization grows and evolves over time, that package can be expanded by defining new APIs or establishing new dependencies.
Furthermore, because using a root package is a convention rather than a technical constraint, the property of composability is not violated. Taking the previously mentioned MySQL Configuration package for example, a user may install it as the root package of their MySQL database control plane, while another user may depend on it as only one component of a much larger API surface for use cases like internal cloud platforms.
Declaring a Vendor Dependency
While the attributes of Crossplane packages enable platform builders to quickly add functionality to their control planes, they also present a unique distribution mechanism for vendors. When your customers all build on a common substrate, you need only target that substrate. Furthermore, the APIs you offer to your customers do not have to be “one size fits all” — there is room for customization both in front and behind the interface.
apiVersion: meta.pkg.crossplane.io/v1
kind: Configuration
metadata:
name: my-org-infra
spec:
crossplane:
version: ">=v1.0.0"
dependsOn:
- provider: xpkg.upbound.io/upbound/provider-aws
version: ">=v0.23.0"
- configuration: xpkg.upbound.io/cool-vendor/dev-envs
version: ">=v1.0.0"
To make it concrete, a Configuration package to deploy the aforementioned hosted development environment product on AWS could establish a dependency on provider-aws, and include a Composition that created an RDS instance. When the customer adds the Configuration package as a dependency in their root package, Crossplane will verify the presence of a compatible version of provider-aws in their control plane.
When the customer interacts with the API offered by the vendor package, the creation of an RDS instance object in the cluster will result in the provisioning of an RDS instance in the customer’s AWS account, subject to all of the policies and constraints they already have in place. Because the vendor’s deployment ultimately depends upon the APIs that the customer’s control plane already offers, a successful deployment implies compliance.
Similarly, the customer is not required to interface with the vendor’s product via the interface that the vendor offers. A common pattern in the Crossplane community is to take an API and wrap it in a higher-level abstraction, optionally including additional resources that are to be provisioned alongside the original.
For example, if a customer wanted to create monitoring and alerting policies that are custom to their organization every time they deployed a developer environment, they could wrap the vendor’s developer environment API and their monitoring APIs in a higher-level abstraction, and only give developers access to interact with the abstract API.
Discovering Your Next Platform Component
To build platforms like the ones described in this post, customers need a place to discover packages and vendors need a means of distribution. The Crossplane community takes advantage of the automatic API documentation and robust discoverability features of the Upbound Marketplace. Search for your next platform component or publish your own, and feel free to reach out in Crossplane Slack if you have any questions!
YOUTUBE.COM/THENEWSTACK
Tech moves fast, don't miss an episode. Subscribe to our YouTube
channel to stream all our podcasts, interviews, demos, and more.