kubernetes-sigs/kro: turning a pile of Kubernetes manifests into one custom resource
kro | Kube Resource Orchestrator
At a glance
- What is it?
- kro is a Kubernetes SIG Cloud Provider subproject that compiles a ResourceGraphDefinition into a new CRD and a dedicated controller, so a group of resources becomes a single object. It is for platform engineers who are tired of hand-wiring Deployments, Services and cloud CRDs together.
- Who is it for?
- Adopt kro if you already run Kubernetes and want a reusable, vendor-agnostic grouping of resources that users instantiate as one object, and if you can accept a v1alpha1 API that the README says may change. Do not adopt it if you need a stable API today, or if your grouping is a single resource that a plain manifest already covers.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem kro targets: resource groups that only exist in someone's head
A Kubernetes application is rarely one object. It is a Deployment, a Service, a ConfigMap, maybe a cloud-managed database custom resource, plus the order in which they must appear. Today that knowledge lives in Helm templates, in a Kustomize overlay, or in a README nobody updates. The README states the project aims to simplify the creation and management of complex custom resources for Kubernetes, and that it provides a Kubernetes-native, vendor agnostic way to define groupings of Kubernetes resources.
The audience is narrow and specific. This is for platform teams that already run a cluster and want to hand application teams something better than a directory of YAML. The README's own example is a WebApp ResourceGraphDefinition that bundles a Deployment and a Service behind a single WebAppCRD, and it notes you can compose a WebAppWithDB by combining that WebApp with a Table custom resource for a managed database instance. That composition story is the real pitch: the grouping is an object, so it can be referenced by another grouping.
If your application is one Deployment and one Service, kro is overhead. You would be introducing a controller, a CRD and an API version to manage two objects you could apply directly.
How the kro controller turns a ResourceGraphDefinition into a running controller
The mechanism is the part worth understanding before installing anything. According to the README FAQ, when a ResourceGraphDefinition is applied, the kro controller verifies its specification, then dynamically creates a new CRD and registers it with the API server. It does not stop there. kro then deploys a dedicated controller to respond to instance events on that CRD, and that microcontroller manages the lifecycle of the resources defined in the ResourceGraphDefinition for each instance created.
So there are two layers of control. The top-level kro controller watches ResourceGraphDefinitions and does the code generation and registration work. The generated microcontroller watches instances of the CRD you just defined. The README also says the controller determines the dependencies between resources and establishes the correct order of operations to create and configure them, which means you declare the resources and their relationships rather than an explicit apply order.
The dependency graph is expressed in the ResourceGraphDefinition specification, and the go.mod shows the project depends on github.com/google/cel-go, which is consistent with a CEL-based expression layer for wiring values between resources. The README excerpt does not spell out the expression syntax, so read the Concepts page at kro.run before designing anything nontrivial.
Installing kro and creating your first ResourceGraphDefinition
The README points installation at the project documentation rather than giving inline commands, so the canonical path is the Installation page at https://kro.run/docs/getting-started/Installation. The repository also ships a helm/ directory and a manifests/ directory, and the Makefile defines HELM_IMAGE as ${OCI_REPO}/charts/kro with OCI_REPO defaulting to registry.k8s.io/kro, which tells you a chart is published under registry.k8s.io/kro/charts/kro. Verify the exact chart version and values against the Installation page before running anything.
The getting-started flow is a two-step apply. First you apply the ResourceGraphDefinition, which the README says kro validates and turns into a CRD plus a controller. Then you apply an instance of that CRD. The README does not reproduce a full ResourceGraphDefinition body, so take the spec shape from the examples/ directory, which contains subdirectories for apigateway, aws, azure, gcp, graph and kubernetes.
After the definition is accepted, you create an instance of the CRD it produced. In the README's WebApp example that means an instance of the WebAppCRD CRD. The README states kro will respond by dynamically creating, configuring, and managing the underlying Kubernetes resources for you. What you should see is the generated CRD in the cluster and, once an instance exists, the Deployment and Service that the definition describes.
The v1alpha1 API and what breaking changes mean for your cluster
The README is direct about this: kro's API is currently at v1alpha1, and as kro evolves the project may introduce breaking changes to improve the API. It commits to clear migration paths, deprecation notices and support, but a commitment is not the same as a guarantee that your ResourceGraphDefinitions keep working across a minor upgrade.
That matters more here than for a typical operator. A ResourceGraphDefinition is not just a config object; it is the source of a CRD that kro registers with the API server, and the source of a running controller. A breaking change to the definition schema can invalidate every instance built on it. The release list shows a v0.10.0-rc.0 alongside v0.9.4 and v0.9.3, so the project is still moving quickly and pre-release tags appear in the same window as patch releases.
The repository does not document rollback of a ResourceGraphDefinition or of generated CRDs in the files available. If you need a downgrade story before you adopt, ask in the #kro channel on Kubernetes Slack, which the README names as where development and discussion is coordinated.
kro vs Crossplane: composition with or without a package manager
The comparison people reach for is Crossplane, and the difference is architectural rather than cosmetic. Crossplane builds on composite resources and compositions that are installed and versioned as packages, with a provider ecosystem for talking to cloud APIs. kro, as described in its README, uses core Kubernetes primitives and stays inside the cluster: you apply a ResourceGraphDefinition, kro generates the CRD and the controller, and instances follow.
That means kro has no package registry, no provider install step and no separate packaging format to learn. It also means kro does not bring its own cloud API clients. If your grouping needs to provision an AWS or GCP resource, you still need the relevant custom resource to exist in the cluster, which is why the examples/ directory has aws, azure and gcp subdirectories rather than a provider layer. The README's WebAppWithDB example makes this explicit: it combines an existing WebApp with a Table custom resource to provision a managed database instance, treating the cloud resource as a CRD someone else provides.
Choose kro when your grouping is mostly native Kubernetes objects plus a few CRDs you already have. Choose Crossplane when the cloud API surface itself is the thing you need managed.
Maintenance, licence and the cost of upgrading a generated controller
The repository is not archived and the last push was on 2026-09-22, with v0.10.0-rc.0 tagged the same day. Development is current. The project sits under Kubernetes SIG Cloud Provider, which is a governance fact rather than a quality claim, and the README lists a community meeting every other Wednesday at 9AM PT with recordings on YouTube.
Upgrade cost is real and specific. Because kro generates a CRD and a controller per ResourceGraphDefinition, an upgrade touches both the kro controller and every generated controller in the cluster. There is no documented migration tooling in the files available, only the README's statement that the project will provide migration paths and deprecation notices. Plan for the upgrade to be a cluster-level operation, not a version bump in a values file.
On licensing, the repository carries Apache-2.0 and a NOTICE file, which is the standard arrangement for Kubernetes SIG projects. Apache-2.0 includes an explicit patent grant and requires you to preserve notices. That is the shape of the licence; whether it fits your distribution model is a question for your own legal review, not something this article can settle.
Editorial conclusion
Adopt kro if you already run Kubernetes and want a reusable, vendor-agnostic grouping of resources that users instantiate as one object, and if you can accept a v1alpha1 API that the README says may change. Do not adopt it if you need a stable API today, or if your grouping is a single resource that a plain manifest already covers. Before you commit, verify one thing: that your cluster can accept a controller that creates CRDs at runtime and runs a microcontroller per ResourceGraphDefinition, since that is the mechanism the whole design rests on.
Frequently asked questions
What is the full form of kro?
kro stands for Kube Resource Orchestrator. The README describes it as a subproject of Kubernetes SIG Cloud Provider that simplifies the creation and management of complex custom resources for Kubernetes.
What does kro do?
It lets you define a group of Kubernetes resources as a ResourceGraphDefinition, which kro validates and turns into a new CRD plus a dedicated controller. Instances of that CRD then cause kro to create and manage the underlying resources.
How do I use kro?
You write a ResourceGraphDefinition specifying one or more Kubernetes resources, apply it to a cluster running the kro controller, then create an instance of the CRD that kro generated from it. The README's example is a WebApp ResourceGraphDefinition composed of a Deployment and a Service.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/kubernetes-sigs-kro)