Introducing function-python

We are excited to announce the first release of Function Python, a powerful new tool that enables you to write Crossplane compositions using Python. This release opens up new possibilities for platform engineers and developers who prefer Python's simplicity and readability when configuring Crossplane.

Function Python was developed by Upbound and has now been contributed to the Crossplane project. This addition strengthens the growing set of tools available for defining compositions with Crossplane.

What Are Crossplane Composition Functions?

In Crossplane, composition functions are custom programs that template Crossplane resources. They allow you to define how composite resources (XRs) should be composed from other Kubernetes resources. When you create a composite resource, Crossplane invokes these functions to determine the resources to create, update, or delete. This approach provides flexibility and enables advanced logic, such as loops and conditionals, in your infrastructure definitions.

Why Use Python for Composition Functions?

Python is renowned for its ease of use and extensive ecosystem. By writing composition functions in Python, you can leverage:

  • Readability: Python's clean syntax makes your composition logic easy to understand and maintain.
  • Rich Libraries: Access to a vast array of libraries and frameworks to enhance your compositions.
  • Rapid Development: Quickly prototype and iterate on your infrastructure definitions.

With Function Python, you can now harness these benefits within the Crossplane ecosystem.

Getting Started with Function Python

To start using Function Python in your Crossplane compositions:

Install the Function: Apply the following manifest to install Function Python:

apiVersion: pkg.crossplane.io/v1
kind: Function
metadata:
  name: function-python
spec:
  package: xpkg.crossplane.io/crossplane-contrib/function-python:v0.1.0

This will deploy the Function Python package into your Crossplane environment.

Define Your Composition: Create a Composition that references the function-python function. Here's an example snippet:

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: example-composition
spec:
  compositeTypeRef:
    apiVersion: example.org/v1alpha1
    kind: XExample
  mode: Pipeline
  pipeline:
    - step: python
      functionRef:
        name: function-python
      input:
        apiVersion: fn.crossplane.io/v1alpha1
        kind: Script
        source: |
          from crossplane.function import v1alpha1 as fn
          def compose(request: fn.RunFunctionRequest) -> fn.RunFunctionResponse:
            rsp.desired.resources["bucket"].resource.update({
                "apiVersion": "s3.aws.upbound.io/v1beta2",
                "kind": "Bucket",
                "spec": {
                    "forProvider": {
                        "region": req.observed.composite.resource["spec"]["region"]
                    }
                },
            })
            rsp.desired.resources["bucket"].ready = True

Your script has access to function-sdk-python. For example you can import crossplane.function.resource. It also has access to the full Python standard library - use it with care.

The RunFunctionRequest and RunFunctionResponse types provided by the SDK are generated from a Protocol Buffers schema. Their fields behave similarly to built-in Python types like lists and dictionaries, but there are some differences. Read the generated code documentation to familiarize yourself with the the differences.

Create Composite Resources: With the composition in place, you can now create composite resources that utilize your Python-based composition logic.

For a comprehensive guide on using composition functions, refer to the Crossplane documentation.

Join the Community

Function Python is an open-source project under the Crossplane Contrib organization. We welcome contributions, feedback, and suggestions from the community. Visit the GitHub repository to report issues, submit pull requests, or explore the source code.

We look forward to seeing how the community leverages Function Python to build their control planes!