KCL: The Game-Changer for Crossplane Composition Building

August 8, 2024

Yury Tsarev

Read time: 8 mins

Share:

In the dynamic realm of cloud-native technologies, Crossplane stands out as a pioneering tool for managing infrastructure through advanced control planes. By extending Kubernetes, Crossplane provides a unified framework to define, deploy, and manage cloud resources through powerful abstractions. Historically, Crossplane was limited to a strictly declarative approach for describing composition logic. However, with the introduction of Composition Functions, a rich language ecosystem has become available for control plane builders. A great example of such capability extension is the ability to express Composition logic with KCL, offering a more expressive and flexible approach to defining infrastructure.

Why KCL Elevates the Developer Experience

KCL, designed with simplicity and robustness in mind, offers a variety of features that significantly improve the developer experience when working with Crossplane. Unlike traditional YAML, KCL provides a more expressive and type-safe environment for defining configurations, reducing the likelihood of syntax errors and increasing productivity.

  1. Declarative and Flexible Syntax: KCL’s syntax is more expressive than YAML, allowing developers to write more concise and readable configurations. This declarative nature of KCL aligns perfectly with the infrastructure-as-code paradigm, enabling developers to describe their desired state in a straightforward manner.
  2. Type Safety and Validation: One of the standout features of KCL is its type-safe nature. It ensures that configurations adhere to predefined types, catching errors early in the development process. This is particularly useful in complex Crossplane compositions where small mistakes can lead to significant issues.
  3. Readability and Brevity: KCL’s concise and readable syntax makes it easier to understand and manage complex configurations. This clarity reduces the risk of misconfigurations and facilitates clearer communication of configuration changes with team members.

Integration with Crossplane

The creators of KCL have made significant contributions to the Crossplane ecosystem, including the development of function-kcl. This project serves as a bridge between KCL and Crossplane, enabling developers to use KCL for defining Crossplane compositions. This integration brings the powerful features of KCL directly into the Crossplane environment, allowing for more streamlined and efficient configuration management.

The function-kcl blog post provides an in-depth look at how KCL enhances Crossplane compositions. It explores the benefits of integrating KCL with Crossplane and provides practical examples of how this combination can streamline the configuration process.

The function-kcl project leverages KCL's capabilities to provide a more robust and user-friendly experience when building Crossplane compositions. By allowing developers to write KCL scripts that generate YAML configurations, it combines the best of both worlds: the readability and maintainability of KCL with the widespread adoption and tooling of YAML.

A Personal Journey with KCL

To showcase the practical benefits of KCL, I’d like to highlight a successful experiment documented in this pull request. In this project, I utilized KCL to enhance the configuration process for AWS EKS clusters.

One of the most notable advantages of KCL was its brevity. The KCL configuration file was significantly shorter compared to the equivalent Patch & Transform YAML representation. This reduction in length made the configuration more manageable and easier to navigate. KCL’s concise syntax felt natural for the form of the API, allowing for a more straightforward and readable configuration.

Moreover, KCL offered just the right level of capability to handle loops and conditionals effectively. This balance provided the flexibility needed to manage complex configurations while maintaining clarity. The combination of brevity and expressive power made KCL an invaluable tool for streamlining the infrastructure management process, reducing the risk of misconfigurations, and simplifying communication of configuration changes with team members.

Key Learning Points for Getting Started with KCL Function

1.  Reading Function Requests and Values

One of the foundational steps in using KCL with Crossplane is understanding how to read function requests and values. The function-kcl documentation provides detailed instructions on using the option function to access input data. Here's an excerpt from the documentation:

1

Here you can find ways to read the input fields from XR, access observed and desired state, get data from the function context and even return custom error messages. 

2. Using Conditionals

KCL supports conditionals, allowing developers to create more dynamic and responsive configurations. An example of using conditionals can be found in the AWS EKS configuration. Here is the relevant code snippet:

1

This feature enhances flexibility and control over the deployment process.

3. Implementing Loops

Another powerful feature of KCL is its support for loops, which can simplify the creation of repetitive resource definitions. An illustrative example is available in the AWS EKS configuration. Here is a snippet demonstrating the use of loops:

1

This capability reduces redundancy and improves the maintainability of the configuration.

4. Passing data between composed resources without the need to patch XR status

Historically, sharing data between composed resources required patching Composite Resource (XR) status, as detailed in the Crossplane patching documentation. This method introduced additional complexity and required extra steps like extending XR spec with the status field, publishing and consuming data from the XR status.

KCL function simplifies this process by allowing data to be passed directly between composed resources within the configuration language itself. This eliminates the need for XR status patching and streamlines the management of data flow between components. With KCL, resources can reference outputs from other resources directly, making configurations more intuitive and reducing the potential for errors.

For example, consider the AWS EKS configuration example, where data from a Cluster resource's atProvider field is read and embedded into the spec of a new SecurityGroup. Here is the relevant snippet:

1

This illustrates KCL’s capability to efficiently facilitate data sharing between resources, simplifying the configuration process and reducing the need for additional steps.

These key learning points provide a foundation for effectively utilizing KCL in Crossplane projects. By mastering these concepts, developers can take full advantage of KCL's powerful features to create robust and dynamic infrastructure configurations. These foundational steps are powerful in bootstrapping Composition building with KCL, but the language itself offers much more depth and functionality to explore, as detailed in the extensive documentation at https://www.kcl-lang.io/. Additionally, the function-kcl examples directory provides a wealth of practical samples that can be reused and adapted for various Crossplane use cases.

Comparison with Other Functions

1. Function-Patch-and-Transform

Before KCL, managing dynamic configurations in Crossplane was facilitated by methods such as function-patch-and-transform. This approach allowed for some level of dynamic configuration by applying patches and transformations to base YAML definitions. While it provided flexibility in modifying static configurations, it was often limited in handling more complex logic like loops and conditionals, which required developers to work within the constraints of YAML.

2. Function-Go-Templating

Another approach in the Crossplane ecosystem has been the use of function-go-templating. This method introduced dynamic features such as loops, conditions, and flow control within YAML templates. While it added the flexibility needed for more complex configurations, it also introduced significant challenges related to maintainability. Managing and debugging complex templated YAML files could quickly become cumbersome, particularly in larger projects where readability and simplicity are crucial.

In contrast, KCL provides a balanced approach that merges the benefits of static YAML with advanced logic capabilities. It offers a cleaner and more maintainable syntax for expressing conditions and iterations, without the drawbacks of extensive templating. KCL’s design simplifies the process of managing complex configurations, making it a compelling choice for modern infrastructure setups.

Advancing the Developer Experience: Beyond KCL Embedded in YAML

While embedding KCL within YAML configurations has been a valuable step forward, it is not the perfect developer experience. The mix of KCL expressions within YAML can sometimes complicate the readability and maintenance of configurations. Recognizing this, I initiated another pull request to enhance our workflow.

In this enhancement, we moved towards using dedicated KCL files for configuration definitions. This approach allows for a clearer separation of concerns, where KCL handles the logic and dynamic aspects, and YAML serves as the output format. By writing configurations in KCL and then generating the necessary YAML for Crossplane compositions, we achieve a more streamlined and maintainable setup. This separation also makes it easier to debug and modify configurations, as the logical structure is contained within the KCL files, while the generated Composition YAML remains clean and focused on its purpose.

KCL Playground: Prototype with Ease

For those looking to quickly prototype KCL data structures and configurations, there is an online KCL Playground available. This interactive environment allows you to experiment with KCL syntax and functionality in real-time. Additionally, the kcl play CLI provides a similar experience locally, offering a convenient way to test and refine KCL scripts on your machine.

Customer Feedback and Future Plans

I’ve already started introducing KCL to Upbound customers, and the feedback has been overwhelmingly positive. Users are appreciating the improved clarity and maintainability that KCL brings to their configuration workflows. We are excited to share a detailed blog post soon, focusing on a real customer story that highlights the adoption of KCL for Composition building.

Conclusion

KCL is revolutionizing the way developers interact with Crossplane. By providing a more expressive, type-safe, and modular approach to configuration management, KCL enhances the developer experience and reduces the complexity associated with building Crossplane compositions. As the Crossplane ecosystem continues to grow, the adoption of KCL will likely play a crucial role in enabling more efficient and error-free infrastructure management.

While KCL does have a learning curve, its extensive documentation and practical examples make the transition smoother. Additionally, resources like the KCL Cheatsheet are incredibly helpful for getting up to speed quickly. A recent webinar hosted by Upbound featured Jared and Viktor, who shared their practical perspectives on KCL. They highlighted that KCL strikes a balance by being less intricate than CUE while avoiding overly simplistic approaches, effectively balancing simplicity and capability.

Whether you're a seasoned Crossplane user or just getting started, integrating KCL into your workflow can provide significant benefits, streamlining the development process and enabling you to focus on what truly matters: building great applications.

If you’d like to dive deeper into your Crossplane journey overall, Viktor and Murph, seasoned Crossplane experts, are going to be covering how to create a fully functional AWS EKS cluster with Upbound/Crossplane using the AWS provider next week. Register now to learn all about it!

Subscribe to the Upbound Newsletter