Add a New KubeVela Capability in Just 20 Minutes
This step‑by‑step tutorial shows how to create a WorkloadDefinition or TraitDefinition for KubeVela, write the corresponding CUE template, merge the YAML and CUE files, apply them to a Kubernetes cluster, and verify the new capability works without restarting the platform.
KubeVela is a cloud‑native application platform that lets engineers extend functionality by registering custom WorkloadDefinition or TraitDefinition resources. The platform’s architecture adds capabilities through a Definition file (registration part) and a CUE template (extension part) that together generate the final Kubernetes objects.
Definition Registration Part
The registration section is a short YAML snippet that declares the API version, kind (WorkloadDefinition or TraitDefinition), metadata name, and a definitionRef pointing to the underlying Kubernetes resource in the form <resources>.<api‑group>. Only the definitionRef.name line carries specific information; the rest follows a fixed schema.
apiVersion: core.oam.dev/v1alpha2
kind: WorkloadDefinition
metadata:
name: webservice
annotations:
definition.oam.dev/description: "Webservice is a workload type to describe long‑running, scalable, containerized services that have a stable network endpoint to receive external traffic."
spec:
definitionRef:
name: deployments.appsCUE Template (Extension) Part
The CUE template is split into two sections: parameter (user‑supplied values) and output (the generated Kubernetes manifest). Parameters can include usage comments, short flags, and default values. The output uses CUE syntax, which is a superset of JSON, allowing omitted quotes, commas, and outer braces.
parameter: {
// +usage=Which image would you like to use for your service
// +short=i
image: string
// +usage=Commands to run in the container
cmd?: [...string]
// +usage=Which port do you want customer traffic sent to
// +short=p
port: *80 | int
// +usage=Define arguments by using environment variables
env?: [...{name: string, value?: string, valueFrom?: {secretKeyRef: {name: string, key: string}}]
// +usage=Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core)
cpu?: string
}
output: {
apiVersion: "apps/v1"
kind: "Deployment"
spec: {
selector: matchLabels: {"app.oam.dev/component": parameter.name}
template: {
metadata: labels: {"app.oam.dev/component": parameter.name}
spec: {
containers: [{
name: parameter.name
image: parameter.image
if parameter.cmd != _|_ {command: parameter.cmd}
if parameter.env != _|_ {env: parameter.env}
ports: [{containerPort: parameter.port}]
if parameter.cpu != _|_ {resources: {limits: {cpu: parameter.cpu}, requests: {cpu: parameter.cpu}}}
}]
}
}
}
}Putting It All Together
Save the registration part in def.yaml and the CUE template in def.cue. Use the helper script provided by KubeVela to merge them into a complete definition file:
./hack/vela-templates/mergedef.sh def.yaml def.cue > mydeploy.yaml
kubectl apply -f mydeploy.yamlAfter applying, the new workload becomes instantly available. List it with vela workloads, then reference it in an Appfile:
name: my-extend-app
services:
mysvc:
type: mydeploy
image: crccheck/hello-world
name: mysvcDeploy the application with vela up -f my-extend-app.yaml and verify the status using vela status my-extend-app. The output shows a healthy pod and confirms that the capability was added without restarting the platform.
Advanced CUE Features
Beyond basic parameters, CUE supports struct types, conditional blocks, optional fields, default values, loops over maps or arrays, and built‑in context variables that automatically inject the application name and other metadata. Annotations prefixed with // +usage and // +short become CLI help text and short flags.
#Config: {
name: string
value: int
other: {key: string, value: string}
}
parameter: {
name: string
image: string
config: [...#Config]
}
output: {
spec: {
containers: [{name: parameter.name, image: parameter.image, env: parameter.config}]
}
}Conditional example:
parameter: {useENV: bool}
output: {
spec: {
containers: [{
name: parameter.name
image: parameter.image
if parameter.useENV == true {env: [{name: "my-env", value: "my-value"}]}
}]
}
}Loop over a map of environment variables:
parameter: {env: [string]: string}
output: {
spec: {
containers: [{
env: [for k, v in parameter.env {name: k, value: v}],
}]
}
}Using the built‑in context variable eliminates the need to pass the service name explicitly:
output: {
spec: {
containers: [{name: context.name, image: parameter.image}]
}
}These features let platform engineers create rich, reusable capabilities that are automatically documented and discoverable in KubeVela’s reference catalog.
Conclusion
The article walks through the complete workflow of adding a new KubeVela capability: defining the registration YAML, writing a CUE template with parameters, merging, applying, and using the capability in an Appfile. It also highlights advanced CUE constructs, built‑in context variables, and annotation‑driven CLI help, enabling rapid, maintainable extensions of cloud‑native platforms.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Alibaba Cloud Native
We publish cloud-native tech news, curate in-depth content, host regular events and live streams, and share Alibaba product and user case studies. Join us to explore and share the cloud-native insights you need.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
