Skip to main content

Trait

A Trait is a composable capability you attach to a Component without changing its ComponentType — persistent storage, autoscaling, a monitoring sidecar, a network policy. Where a ComponentType defines the base shape of a workload, a Trait is an overlay any compatible component can opt into. A component can attach the same Trait multiple times using distinct instance names.

A ClusterTrait is the cluster-scoped variant; the platform's shared cross-cutting capabilities ship as ClusterTraits.

KindTrait / ClusterTrait
API groupopenchoreo.dev/v1alpha1
ScopeNamespaced / Cluster
AudiencePlatform engineer
Attached byComponent (spec.traits[])
Gated byComponentType allowedTraits

Key spec fields

FieldWhat it does
spec.parameters.openAPIV3SchemaWhat a developer sets per trait instance (mount path, volume name)
spec.environmentConfigs.openAPIV3SchemaWhat's overridable per environment via the binding (size, storage class)
spec.creates[]New Kubernetes resources the Trait adds (PVC, ConfigMap, ServiceMonitor)
spec.patches[]JSON-Patch modifications to resources the ComponentType already produced (add a volume, inject env, attach a sidecar)

Creates vs patches is the conceptual core: creates generate new resources; patches reach into the resources the ComponentType made (with array-filtered paths like containers[?(@.name=='main')]) without the ComponentType knowing the Trait exists.

Create in the portal

  1. Open Create…Platform ResourcesClusterTrait (or Trait for namespace scope).
  2. In the in-portal YAML editor, define the parameter / environment schemas, the creates, and the patches.
  3. Click Create. Allow it on a ComponentType via allowedTraits so developers can attach it.

Full guide: Traits.

Example

A persistent-volume ClusterTrait — creates a PVC and patches the Deployment to mount it:

apiVersion: openchoreo.dev/v1alpha1
kind: ClusterTrait
metadata:
name: persistent-volume
spec:
parameters:
openAPIV3Schema:
type: object
properties:
volumeName: { type: string }
mountPath: { type: string }
environmentConfigs:
openAPIV3Schema:
type: object
properties:
size: { type: string, default: "10Gi" }
creates:
- template:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ${metadata.name}-${trait.instanceName} # unique per attachment
namespace: ${metadata.namespace}
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: ${environmentConfigs.size}
patches:
- target: { kind: Deployment, group: apps, version: v1 }
operations:
- op: add
path: /spec/template/spec/volumes/-
value:
name: ${parameters.volumeName}
persistentVolumeClaim:
claimName: ${metadata.name}-${trait.instanceName}

trait.instanceName is what makes the same Trait attachable multiple times.

See also