6.0 KiB
The Complete Technical Guide to CUE (Configure-Unify-Execute)
A structured, practical, and comprehensive introduction to CUE—covering core concepts, real-world applications, and best practices.
1. Introduction to CUE
What is CUE?
CUE (Configure-Unify-Execute) is an open-source data constraint language developed at Google. It is designed for:
- Configuration management (Kubernetes, Terraform, CI/CD)
- Data validation (API schemas, input sanitization)
- Code generation (Dockerfiles, Kubernetes manifests, SQL schemas)
- Policy enforcement (security rules, compliance checks)
Unlike YAML/JSON, CUE merges types, values, and constraints into a single model, enabling deterministic, reproducible configurations.
Why CUE Over Alternatives?
| Tool | Strengths | Weaknesses vs. CUE |
|---|---|---|
| YAML | Human-readable, widely used | No validation, no logic, fragile |
| Jsonnet | Templating, code reuse | Slower, no built-in validation |
| HCL | Terraform integration | Less flexible for non-TF use |
| Pulumi | Full programming model | Complex, runtime-dependent |
| CUE | Validation + unification | Steeper initial learning curve |
2. Core Concepts
The CUE Lattice
CUE’s power comes from its lattice structure, where:
_(Top): Accepts any value (e.g.,string,int,{})._|_(Bottom): An invalid/conflicting value (error state).- Unification (
&) combines constraints (like logical AND). - Disjunction (
|) allows alternatives (like logical OR).
Example:
#Schema: {
name: string & =~"^[A-Z][a-z]+$" // Must start with uppercase
age: int & >0 & <120 // Age between 0 and 120
role?: "admin" | "user" // Optional role
}
valid: #Schema & { name: "Alice", age: 30 } // ✅ Valid
invalid: #Schema & { name: "alice", age: 150 } // ❌ Fails (name, age)
3. Getting Started
Installation
# Install CUE
brew install cue-lang/tap/cue # macOS
sudo apt-get install cue # Debian/Ubuntu
go install cuelang.org/go/cmd/cue@latest # Go users
# Verify
cue version
Basic Workflow
- Define schemas (
.cuefiles). - Validate data (
cue vet). - Export to JSON/YAML (
cue export).
Example:
// schema.cue
#Person: {
name: string
age: int & >=18
}
// data.json
{ "name": "Bob", "age": 25 }
# Validate
cue vet schema.cue data.json # ✅ Passes
4. Real-World Use Cases
Case 1: Kubernetes Configuration
Problem: YAML files are brittle and hard to validate.
Solution: Define a reusable schema.
// k8s.cue
#Deployment: {
apiVersion: "apps/v1"
kind: "Deployment"
metadata: name: string
spec: {
replicas: int & >=1
template: spec: containers: [{
name: string
image: string & =~".+:.+"
}]
}
}
myapp: #Deployment & {
metadata: name: "webapp"
spec: replicas: 3
spec: template: spec: containers: [{ name: "app", image: "nginx:latest" }]
}
# Export to YAML
cue export k8s.cue -e myapp --out yaml > deploy.yaml
Case 2: Terraform Guardrails
Problem: Prevent invalid cloud configurations.
Solution: Enforce AWS/GCP policies.
#AWS: {
region: "us-east-1" | "us-west-2"
instanceType: "t2.micro" | "t3.medium"
}
my_vm: #AWS & {
region: "us-east-1"
instanceType: "t2.micro" # ✅ Valid
}
invalid_vm: #AWS & {
region: "eu-west-1" # ❌ Fails (invalid region)
}
Case 3: CI/CD Pipeline-as-Code
Problem: YAML-based pipelines are hard to maintain.
Solution: Define pipelines in CUE.
#Pipeline: {
steps: [...{
name: string
cmd: string
}]
}
my_pipeline: #Pipeline & {
steps: [
{ name: "build", cmd: "go build" },
{ name: "test", cmd: "go test" },
]
}
# Generate GitHub Actions YAML
cue export pipeline.cue --out yaml > .github/workflows/ci.yml
5. Debugging & Best Practices
Debugging Unification Errors
- Use
cue eval -vto trace unification steps. - Check for
_|_(bottom) in output—indicates conflicts.
Best Practices
- Modularize: Split schemas into files (
schemas/,configs/). - Reuse: Leverage CUE’s import system (
import "acme.com/schemas"). - Validate Early: Run
cue vetin CI/CD.
6. Advanced Topics
Go + CUE Integration
Embed CUE in Go programs for dynamic validation:
package main
import (
"cuelang.org/go/cue/cuecontext"
"fmt"
)
func main() {
ctx := cuecontext.New()
schema := ctx.CompileString(`
#Person: {
name: string
age: int & >=18
}`)
data := ctx.CompileString(`{ name: "Alice", age: 30 }`)
unified := schema.Unify(data)
if err := unified.Validate(); err != nil {
fmt.Println("Validation failed:", err)
} else {
fmt.Println("Valid!")
}
}
Generating Code
Convert CUE to:
- OpenAPI:
cue export --out openapi - Go Structs:
cue get go - SQL: Use templates (
text/template).
7. Learning Resources
- Official Docs: cuelang.org
- Playground: cuelang.org/play
- Community: CUE Slack
Conclusion
CUE replaces ad-hoc YAML/JSON with structured, validated, and reusable configurations. By mastering:
- Lattice logic (unification, constraints),
- Real-world workflows (K8s, Terraform, CI/CD),
- Tooling integration (Go, OpenAPI),
You can eliminate configuration errors and enforce policies declaratively.
Next Step: Try the CUE Tutorial or experiment in the playground! 🚀