CUE Language Cheat Sheet
Overview
CUE (Configure, Unify, Execute) is an open-source language designed for defining, generating, and validating data. It combines the power of a type system with a configuration language, allowing you to write schemas that validate JSON, YAML, and other formats. CUE uses a constraint-based approach where types and values exist on the same spectrum.
CUE excels at configuration management for Kubernetes, CI/CD pipelines, and infrastructure-as-code. It can validate existing YAML/JSON files, generate configurations from templates, and reduce boilerplate through its powerful unification and inheritance model.
Installation
# macOS
brew install cue-lang/tap/cue
# Linux
curl -LO https://github.com/cue-lang/cue/releases/latest/download/cue_v0.9.0_linux_amd64.tar.gz
tar xzf cue_v0.9.0_linux_amd64.tar.gz
sudo mv cue /usr/local/bin/
# Go install
go install cuelang.org/go/cmd/cue@latest
# Verify
cue version
Core Commands
| Command | Description |
|---|---|
cue eval | Evaluate and print CUE files |
cue export | Export CUE to JSON/YAML |
cue vet | Validate data against schema |
cue fmt | Format CUE files |
cue def | Print CUE definitions |
cue trim | Remove redundant fields |
cue import | Import JSON/YAML into CUE |
cue mod init | Initialize a CUE module |
cue cmd | Run custom CUE commands |
Language Basics
Types and Values
// basic_types.cue
// Basic types
name: string
age: int
score: float
active: bool
data: bytes
// Concrete values (also valid types)
greeting: "hello"
count: 42
ratio: 3.14
enabled: true
// Constraints
port: int & >=1 & <=65535
status: "active" | "inactive" | "pending"
email: =~"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
// Optional fields
address?: string
phone?: string
// Default values
region: *"us-east-1" | string
retries: *3 | int
Structs and Lists
// Struct
server: {
host: string
port: int | *8080
tls: bool | *false
}
// Closed struct (no additional fields allowed)
#Config: {
name: string
version: string
debug: bool | *false
}
// List
ports: [80, 443, 8080]
names: [...string] // list of strings
scores: [int, int, int] // exactly 3 ints
// Nested
database: {
primary: {
host: "db-primary.example.com"
port: 5432
}
replicas: [...{
host: string
port: int | *5432
}]
}
Definitions (Schemas)
// definitions.cue
#Deployment: {
apiVersion: "apps/v1"
kind: "Deployment"
metadata: {
name: string
namespace: string | *"default"
labels: [string]: string
}
spec: {
replicas: int & >=1 & <=100
selector: matchLabels: [string]: string
template: spec: containers: [...#Container]
}
}
#Container: {
name: string
image: string
ports: [...{
containerPort: int & >=1 & <=65535
protocol: *"TCP" | "UDP"
}]
resources?: #Resources
}
#Resources: {
requests?: {cpu?: string, memory?: string}
limits?: {cpu?: string, memory?: string}
}
Configuration
Exporting to JSON/YAML
# Export to JSON
cue export config.cue
# Export to YAML
cue export config.cue --out yaml
# Export specific expression
cue export config.cue -e deployment
# Export with concrete values
cue export config.cue --force
Validating Data
# Validate YAML against CUE schema
cue vet schema.cue data.yaml
# Validate JSON
cue vet schema.cue data.json
# Validate with concrete check
cue vet -c schema.cue data.yaml
Importing Existing Data
# Import YAML to CUE
cue import deployment.yaml
# Import with package name
cue import -p myapp deployment.yaml
# Import with schema
cue import -f -p myapp -l 'strings.ToLower(kind)' k8s/*.yaml
Advanced Usage
Comprehensions and Loops
services: ["web", "api", "worker"]
deployments: {
for s in services {
(s): {
name: s
replicas: 2
image: "myregistry/\(s):latest"
}
}
}
// Conditional fields
#Environment: {
name: string
if name == "production" {
replicas: 3
monitoring: true
}
if name != "production" {
replicas: 1
monitoring: false
}
}
Packages and Modules
# Initialize module
cue mod init github.com/myorg/myconfig
// schema/types.cue
package schema
#Service: {
name: string
port: int
replicas: int | *1
}
// config/prod.cue
package config
import "github.com/myorg/myconfig/schema"
webService: schema.#Service & {
name: "web"
port: 8080
replicas: 3
}
Kubernetes Configuration
package k8s
_base: {
apiVersion: "apps/v1"
kind: "Deployment"
metadata: labels: app: metadata.name
spec: {
replicas: *1 | int
selector: matchLabels: app: metadata.name
template: {
metadata: labels: app: spec.selector.matchLabels.app
spec: containers: [{
name: metadata.name
image: _image
ports: [{containerPort: _port}]
}]
}
}
}
frontend: _base & {
metadata: name: "frontend"
_image: "frontend:v1.2.0"
_port: 3000
spec: replicas: 2
}
backend: _base & {
metadata: name: "backend"
_image: "backend:v2.0.0"
_port: 8080
spec: replicas: 3
}
Custom Commands (Tooling)
// deploy_tool.cue
package main
import (
"tool/exec"
"tool/cli"
)
command: deploy: {
ask: cli.Ask & {
prompt: "Deploy to production? [y/n]"
response: string
}
run: exec.Run & {
$after: ask
cmd: ["kubectl", "apply", "-f", "-"]
stdin: yaml.Marshal(deployment)
}
}
cue cmd deploy
Troubleshooting
| Issue | Solution |
|---|---|
incomplete value error | Provide concrete values for all required fields |
conflicting values | Check for contradictory constraints in unification |
| Import fails | Verify file format; use -f to force overwrite |
| Schema too strict | Use ... to allow additional fields in structs |
| Module not found | Run cue mod init and check import paths |
| Validation passes when it shouldn’t | Use cue vet -c for concrete validation |
# Debug evaluation
cue eval -c config.cue
# Show all definitions
cue def config.cue
# Format files
cue fmt ./...
# Trim redundant fields
cue trim config.cue