| title | Trait API Reference |
|---|
A Trait represents a cross-cutting concern that can be attached to components to add additional capabilities like persistent storage, observability, security policies, or service mesh integration. Traits modify or extend the resources generated by ComponentTypes without requiring changes to the ComponentType itself.
openchoreo.dev/v1alpha1
Traits are namespace-scoped resources typically created in an Organization's namespace to be available for components in that organization.
apiVersion: openchoreo.dev/v1alpha1
kind: Trait
metadata:
name: <trait-name>
namespace: <org-namespace> # Organization namespace| Field | Type | Required | Default | Description |
|---|---|---|---|---|
schema |
TraitSchema | No | - | Configurable parameters for this trait |
creates |
[TraitCreate] | No | [] | New Kubernetes resources to create |
patches |
[TraitPatch] | No | [] | Modifications to existing ComponentType resources |
Defines the configurable parameters that developers can set when attaching this trait to a component.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
types |
object | No | - | Reusable type definitions referenced in parameters |
parameters |
object | No | - | Developer-facing configuration options |
envOverrides |
object | No | - | Parameters that can be overridden per environment |
Uses the same inline schema syntax as ComponentType: a single pipe after the type, then space-separated constraints:
fieldName: "type | default=value enum=val1,val2"
Example:
schema:
parameters:
volumeName: string
mountPath: string
containerName: "string | default=app"
envOverrides:
size: "string | default=10Gi"
storageClass: "string | default=standard"Defines a new Kubernetes resource to be created when the trait is applied.
| Field | Type | Required | Description |
|---|---|---|---|
template |
object | Yes | Kubernetes resource template with CEL expressions |
CEL expressions in trait templates have access to:
metadata.*- Component metadatatrait.*- Trait parameters and instance nameparameters.*- Component parametersenvironment.*- Environment information
Defines modifications to existing resources generated by the ComponentType.
| Field | Type | Required | Description |
|---|---|---|---|
forEach |
string | No | CEL expression for iterating over a list |
var |
string | No | Variable name for forEach iterations (required if forEach set) |
target |
PatchTarget | Yes | Specifies which resource to patch |
operations |
[JSONPatchOperation] | Yes | List of JSONPatch operations to apply |
Specifies which Kubernetes resource to modify.
| Field | Type | Required | Description |
|---|---|---|---|
group |
string | No | API group (empty for core resources) |
version |
string | Yes | API version (e.g., "v1", "v1beta1") |
kind |
string | Yes | Resource type (e.g., "Deployment", "StatefulSet") |
where |
string | No | CEL expression to filter which resources to patch |
Defines a modification using JSONPatch format (RFC 6902) with OpenChoreo extensions.
| Field | Type | Required | Description |
|---|---|---|---|
op |
string | Yes | Operation: add, replace, remove |
path |
string | Yes | JSON Pointer to the field (RFC 6901) |
value |
any | No | Value to set (not used for remove) |
- add: Add a new field or array element
- replace: Replace an existing field value
- remove: Delete a field
Supports array filters for targeting specific elements:
/spec/containers[?(@.name=='app')]/volumeMounts/-
apiVersion: openchoreo.dev/v1alpha1
kind: Trait
metadata:
name: persistent-volume
namespace: default
spec:
schema:
parameters:
volumeName: string
mountPath: string
containerName: "string | default=app"
envOverrides:
size: "string | default=10Gi"
storageClass: "string | default=standard"
creates:
- template:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ${metadata.name}-${trait.instanceName}
namespace: ${metadata.namespace}
spec:
accessModes:
- ReadWriteOnce
storageClassName: ${trait.parameters.storageClass}
resources:
requests:
storage: ${trait.parameters.size}
patches:
- target:
group: apps
version: v1
kind: Deployment
operations:
- op: add
path: /spec/template/spec/containers[?(@.name=='${trait.parameters.containerName}')]/volumeMounts/-
value:
name: ${trait.parameters.volumeName}
mountPath: ${trait.parameters.mountPath}
- op: add
path: /spec/template/spec/volumes/-
value:
name: ${trait.parameters.volumeName}
persistentVolumeClaim:
claimName: ${metadata.name}-${trait.instanceName}apiVersion: openchoreo.dev/v1alpha1
kind: Trait
metadata:
name: logging-sidecar
namespace: default
spec:
schema:
parameters:
logPath: "string | default=/var/log/app"
sidecarImage: "string | default=fluent/fluent-bit:latest"
patches:
- target:
group: apps
version: v1
kind: Deployment
operations:
- op: add
path: /spec/template/spec/containers/-
value:
name: log-collector
image: ${trait.parameters.sidecarImage}
volumeMounts:
- name: logs
mountPath: ${trait.parameters.logPath}
- op: add
path: /spec/template/spec/volumes/-
value:
name: logs
emptyDir: {}apiVersion: openchoreo.dev/v1alpha1
kind: Trait
metadata:
name: resource-limits
namespace: default
spec:
schema:
envOverrides:
cpuLimit: "string | default=1000m"
memoryLimit: "string | default=512Mi"
patches:
- target:
group: apps
version: v1
kind: Deployment
operations:
- op: add
path: /spec/template/spec/containers[?(@.name=='main')]/resources/limits/cpu
value: ${trait.parameters.cpuLimit}
- op: add
path: /spec/template/spec/containers[?(@.name=='main')]/resources/limits/memory
value: ${trait.parameters.memoryLimit}apiVersion: openchoreo.dev/v1alpha1
kind: Trait
metadata:
name: multi-volume
namespace: default
spec:
schema:
types:
Mount:
name: string
path: string
parameters:
mounts: "[]Mount"
patches:
- target:
group: apps
version: v1
kind: Deployment
forEach: ${trait.parameters.mounts}
var: mount
operations:
- op: add
path: /spec/template/spec/volumes/-
value:
name: ${mount.name}
emptyDir: {}
- op: add
path: /spec/template/spec/containers[?(@.name=='app')]/volumeMounts/-
value:
name: ${mount.name}
mountPath: ${mount.path}Developers attach traits to components in the Component specification:
apiVersion: openchoreo.dev/v1alpha1
kind: Component
metadata:
name: my-service
spec:
componentType: deployment/service
traits:
- name: persistent-volume
instanceName: data-storage
parameters:
volumeName: data
mountPath: /var/data
containerName: app
envOverrides:
size: 20Gi
storageClass: fast-ssdPlatform engineers can also override trait parameters in ComponentDeployment:
apiVersion: openchoreo.dev/v1alpha1
kind: ComponentDeployment
metadata:
name: my-service-production
spec:
componentName: my-service
environment: production
traitOverrides:
- instanceName: data-storage
parameters:
size: 100Gi
storageClass: production-ssd- Single Responsibility: Each trait should address one cross-cutting concern
- Naming: Use descriptive names that indicate the capability being added
- Parameters: Provide sensible defaults for all non-required parameters
- Target Specificity: Use
whereclauses when needed to avoid unintended modifications - Testing: Test traits with different ComponentTypes to ensure compatibility
- Documentation: Document which ComponentTypes a trait is designed to work with
- Idempotency: Ensure traits can be safely applied multiple times
| Aspect | ComponentType | Trait |
|---|---|---|
| Purpose | Defines core deployment pattern | Adds cross-cutting concerns |
| Scope | One per component | Multiple can be attached to one component |
| Resources | Creates primary workload resources | Creates supplementary resources or patches existing ones |
| Modification | Determines base resource structure | Modifies or extends ComponentType resources |
| Examples | Service, WebApp, ScheduledTask | Persistent Storage, Logging, Security |
- ComponentType - Defines the base deployment pattern
- Component - Attaches traits to components
- ComponentDeployment - Can override trait parameters per environment