Let your users define their workloads with simple CUE schemas.
Hide complexity of your deployment platform by implementing wrappers around configuration definition, secrets/certificates retrieval, monitoring ...
Key Features:
- Single Source of Truth: Define workloads once, deploy anywhere (thanks to dedicated backends)
- Type Safety: Leverage CUE's powerful type system for validation
- Secret/Certificate Management: Integrated Vault
- Dependency Management: Declare workload dependencies explicitly
- Configuration as Code: Version control your entire deployment configuration
- Multiple Backend Support: Generate configurations for Docker Compose and Kubernetes
A workload is the fundamental unit that combines:
- Container: Image specification (registry, name, tag)
- Expose: Port mappings and TLS certificates
- Configs: Configuration files with inline data
- Secrets: Vault-backed secrets (environment variables or files)
- Volumes: Persistent or ephemeral storage mounts
- Dependencies: Explicit dependencies on other workloads
- Probes: Health check definitions (liveness, readiness, startup)
- Docker Compose: Transforms workloads into
docker-compose.yaml - Kubernetes: Generates Deployments, ConfigMaps, ExternalSecrets, and SecretStore manifests
- Mermaid: Generates state diagrams showing workload dependencies
cue cmd kubeApply to your cluster:
cue cmd kube | kubectl apply -f -cue cmd composeThis command:
- Generates
docker-compose.yamlto stdout - Creates configuration files in
.generated/<workload>-<configname>/
Deploy with Docker Compose:
cue cmd compose | docker compose -f - up -dcue cmd mermaidThis generates a Mermaid state diagram showing workload dependencies.
Ensure data match specifications
cue vet ./...Visualize specific manifest
cue export ./backends/kube.cue --out yaml -e manifests.service_redisSecrets must use typed definitions:
Environment Variable Secret:
secrets: dbpassword: schemas.#SecretEnv & {
path: "database/password"
}File-Based Secret:
secrets: credentials: schemas.#SecretFile & {
path: "app/credentials"
mount: "/run/secrets/credentials"
}For Kubernetes deployments, secrets are retrieved from Vault using the CSI driver.
Ephemeral Volume (emptyDir):
volumes: tmp: schemas.#VolumeDir & {
mount: "/tmp"
}Host Path Volume:
volumes: hostdata: schemas.#VolumeBind & {
source: "/host/path"
mount: "/container/path"
}Certificates are retrieved from Vault PKI backend:
expose: {
ports: "443": {}
certs: "tls": {
pki: "pki"
commonName: "myapp.default.svc.cluster.local"
altNames: ["myapp", "localhost"]
ttl: "720h"
}
}Declare explicit dependencies between workloads:
workloads: {
webapp: schemas.#Workload & {
// ...
deps: [workloads.redis, workloads.postgres]
}
}Define liveness, readiness, and startup probes:
TCP Probe:
probes: liveness: schemas.#ProbeTcp & {
port: 6379
}HTTP Probe:
probes: readiness: schemas.#ProbeHttp & {
port: 8080
path: "/health"
}The Kubernetes backend behaviors:
- Automatically generates standard manifests (Deployments, ConfigMaps, Services, SecretProviderClass) from your workload definitions
- ConfigMaps are mounted as volumes
- Port exposure requires separate Service definitions (not generated)
- Secrets are synced from Vault via CSI driver
- Certificates are mounted via CSI driver from Vault PKI
You can customize or extend these manifests using the manifests field (in the backends package).
You can add additional Kubernetes resources by defining them in the manifests field in backends/kube.cue:
manifests: {
// Generated manifests (ConfigMaps, Deployments, etc.)
// ...
// Add a custom Ingress resource
"ingress_myapp": networkingv1.#Ingress & {
metadata: {
name: "myapp-ingress"
annotations: {
"nginx.ingress.kubernetes.io/rewrite-target": "/"
}
}
spec: {
rules: [{
host: "myapp.example.com"
http: paths: [{
path: "/"
pathType: "Prefix"
backend: service: {
name: "myapp"
port: number: 80
}
}]
}]
}
}
}You can override any generated manifest by using the same key. For example, to customize the Service for a workload:
manifests: {
// This replaces the auto-generated LoadBalancer service for "myapp"
"service_myapp": corev1.#Service & {
metadata: {
name: "myapp"
labels: app: "myapp"
annotations: {
"service.beta.kubernetes.io/aws-load-balancer-type": "nlb"
}
}
spec: {
type: "ClusterIP" // Change from LoadBalancer to ClusterIP
selector: app: "myapp"
ports: [{
name: "http"
port: 80
targetPort: 8080
}]
}
}
}Generated manifests follow these naming conventions:
config-map_<workload>_<configname>: ConfigMap resourcessecret-provider-class_<workload>: SecretProviderClass resourcesdeployment_<workload>: Deployment resourcesservice_<workload>: Service resources
Use these keys to replace generated manifests or create new ones with custom keys.
Behaviors:
- Writes ConfigMaps to
.generated/directory to mount it in a volume