13 KiB
Welcome to the world of CUE – Configure-Unify-Execute – a language that turns the usual “write YAML and pray” workflow into something that feels almost… serendipitous.
In CUE you don’t imperatively build configs, websites, DB schemas, or API specs.
Instead you declare the shape, constraints and defaults you want, then let CUE’s graph-unification engine search the (enormous but finite) space of legal values and hand you back the one deterministic result that satisfies every rule.
That moment when cue export suddenly spits out the exact JSON or SQL DDL you needed? Deterministic serendipity – reproducible, cacheable, diff-able.
A 30-second taste:
package site
#Page: {
title: string & =~"^[A-Z].*"
path: string & =~"^/[a-z0-9/-]+$"
meta: {
description: string & strings.MinRunes(30) & strings.MaxRunes(160)
keywords: [...string] & list.Unique()
}
}
home: #Page & {
title: "Welcome to the World of CUE"
path: "/"
meta: keywords: ["cue", "configure", "unify", "execute"]
}
Run cue export home and you get the exact JSON your static-site generator needs, with every constraint already proven.
Change a single keyword and CUE re-unifies, yielding a new but still deterministic artefact.
The same file can:
- generate OpenAPI specs, Terraform, Kubernetes YAML
- validate incoming JSON requests at runtime
- spit out SQL DDL and Go structs (
cue get go) or even HTML via a tiny script
Because CUE merges types, values and constraints into one concept, the usual inheritance hell disappears: you compose by unification (&) instead of copy-paste or fragile overrides.
So yes – in the CUE universe you write a handful of declarations, run cue, and the “accidental” correct configuration pops out every single time.
Raw deterministic serendipity, no runtime surprises, no “works on my machine”.
CUE (Configure-Unify-Execute) is an open-source data constraint language developed at Google, designed for configuration management, validation, and templating. It stands for Configure, Unify, Execute.
Purpose
CUE simplifies tasks involving defining, validating, and using data in complex systems like Kubernetes. It combines schemas, constraints, and values into a unified framework, ensuring configurations adhere to predefined rules.
Key Features
- Validation First: Unlike traditional languages, CUE prioritizes validation, ensuring data meets strict criteria.
- JSON Superset: It builds upon JSON, adding logic like conditionals and loops.
- Constraint-Based: Uses constraints instead of inheritance, avoiding complexity from order-dependent merging.
- Order Independence: Merging configurations is associative, commutative, and idempotent, ensuring consistency regardless of merge order.
- Tooling: Offers CLI tools (
cuecommand), APIs for automation, and integrations with YAML/JSON.
Use Cases
- Kubernetes: Validate and generate YAML configurations.
- Data Validation: Define schemas for APIs or infrastructure.
- Code Generation: Extract schemas from source code or generate code from CUE definitions.
- CI/CD Pipelines: Ensure deployment consistency.
Example
In CUE, you might define a schema for a Kubernetes deployment, enforce constraints (e.g., resource limits), and generate validated YAML—all in one workflow.
Summary
CUE is a robust, constraint-driven language that unifies configuration, validation, and execution, particularly valuable for managing complex, policy-driven systems like cloud infrastructure.
Here are six starter ideas that feel more like “mini-projects” than “hello-world” exercises. Each one is scoped to be finished in an evening or weekend and leaves you with something useful you can actually commit to a repo or show a teammate.
-
“Pet-Picture” API Contract
• Goal: Design the request/response contract for a tiny REST service that lets users POST pictures of their pets.
• CUE angle
– Write a#PetPhotoschema with required fields (id,petName,imageURL), plus constraints (URL must start withhttps://, file size ≤ 5 MB, allowed MIME types).
– Export the same CUE to JSON Schema so front-end folks can use it in Swagger / OpenAPI.
• Quick win:curla sample payload throughcue vetin CI and watch it reject the 6 MB GIF someone tried to sneak in . -
Terraform Variable Guardrails
• Goal: Stop teammates from fat-fingering Azure VM sizes or AWS regions in your Terraform repo.
• CUE angle
– Describe all valid regions, SKUs, and tag patterns in CUE.
– Make avariables.cuethat unifies with every.tfvarsfile in the repo; fail the plan if anything is wrong .
• Quick win: open a PR that deliberately violates the policy and see GitHub Actions reject it in <30 s. -
Team Dotfiles Distribution
• Goal: Ship a single YAML/JSON file per engineer that declares their preferred shell, VS Code extensions, and git aliases.
• CUE angle
– Provide a#Workstationschema with defaults (shell ="zsh", extensions =[ "GitLens", "k9s" ]).
– Write a 20-line Go program that ingests the unified CUE value and spits out the right Ansible or Home-Brew bundle per person . -
Kubernetes “Golden Path” Templates
• Goal: Give devs a one-command way to generate a Deployment + Service + HPA that already meets security and resource standards.
• CUE angle
– Create a#Microservicedefinition that enforces labels, resource limits, and security contexts.
– Provide optional overlays (staging vs prod) that inject different image registries or replica counts .
• Quick win:cue cmd gen prod my-appwritesprod-my-app.yamlwith zero copy-paste. -
Resume-as-Data
• Goal: Host your résumé as YAML but still be able to export to PDF, JSON, and HTML.
• CUE angle
– Model sections (experience,education,skills) with strict types and regex rules (company names must match LinkedIn URLs).
– Usecue exportto feed a Go template that renders LaTeX or Markdown.
• Quick win: change one bullet in YAML, rerunmakeand see every output format refresh. -
Advent-of-Code Input Validator
• Goal: Stop wasting time on malformed puzzle inputs.
• CUE angle
– For any AoC day, capture the input grammar in CUE (grids, ints, regex groups).
– Add constraints (board size 100×100, numbers 0-9 only).
• Quick win: paste your downloaded input intoinput.txt;cue vettells you immediately if the site changed the format overnight.
How to pick one
• If you live in Terraform → start with #2.
• If you just want to “see CUE do magic” → #1 or #5 finishes in <30 min.
• If you’re already on K8s → #4 will save you real toil next sprint.
Each repo can literally be a folder with a schema.cue, a data.* file, and a two-line GitHub Action that runs cue vet. Ship it, tag a friend for review, and you’ve officially gone from “reading about CUE” to “running CUE in production.”
Below is a step-by-step brainstorm that keeps the promise:
“Everything is an object” → expressed in CUE → rendered into one or more Docker containers → deployed on stock Debian.
We iterate together—after each numbered idea you can simply reply “next” or “deep-dive ” and I’ll expand only the one you like.
-
Object–Music Player (OM-Player)
• Object model: every track, playlist, device, volume-level, EQ preset is a CUE object.
• CUE → Docker trick:cue export om.cue | cue cmd gen docker-compose.ymlyields three containers (MPD server, web-UI, icecast stream).
• Deploy:./deploy.shon a Debian box auto-pulls images, mounts/music, and exposes port 8000.
• Hook: you can change “cross-fade = 2.0s” in the CUE file, runcue vet, and the compose file re-renders without touching YAML by hand. -
Object–Photo Darkroom (OM-Darkroom)
• Object model: raw image, transform pipeline (crop 1:1 → denoise → LUT), export profiles.
• CUE → Docker trick: single multi-stage Dockerfile generated from CUE; includes conditional GPU layer ifgpu: true.
• Deploy: on Debian with or without NVIDIA Docker runtime .
• Hook:cue eval darkroom.cueshows you the exact ImageMagick CLI that will run inside the container before you ever build. -
Object–Home-Lab Router (OM-Router)
• Object model: interface objects, VLAN objects, nftables rule objects, WireGuard peer objects.
• CUE → Docker trick: produces a privileged container that maps/etc/wireguard,/etc/nftables; plus a dry-run sidecar container that just prints the rules it would apply.
• Deploy: systemd service on Debian host starts the container at boot.
• Hook:cue vetguarantees that no two VLANs share the same ID, no overlapping subnets, etc. -
Object–FaaS Edge (OM-Edge)
• Object model: every function is an object (fn,runtime,env,memory,cpu).
• CUE → Docker trick: CUE spawns one container per function plus an nginx reverse-proxy container.
• Deploy: Debian box becomes a mini Lambda—curl /fn/hellotriggers the container of the moment.
• Hook: horizontal scale is just changingreplicas: 3in CUE and re-exporting. -
Object–Minecraft World (OM-Mine)
• Object model: world seed, player objects, permission objects, mod objects.
• CUE → Docker trick: Server container + optional RCON web UI container.
• Deploy: on Debian; mods are baked into the image hash calculated from the CUE file.
• Hook: roll back to yesterday’s world by reverting one Git commit to the CUE file and redeploying. -
Object–CI Matrix (OM-Matrix)
• Object model: every job, step, runner label, secret ref is an object.
• CUE → Docker trick: generates a lightweight Drone-CI server + runner containers.
• Deploy: singledocker compose upon Debian; self-hosted CI in < 2 min.
• Hook: matrix expansion (go: [1.21, 1.22]) happens in CUE, not in YAML anchors.
Your turn
Reply with the number you want to pursue (or say “new batch”) and I’ll give:
- Minimal CUE schema
- Exact
docker-compose.ymlgenerator snippet - One-liner to run it on a fresh Debian install
Yes — there are very concrete reasons to pair Go + CUE that do not apply (or apply only weakly) to other language stacks.
Below is a concise decision grid you can paste into an ADR or RFC.
| Benefit | Why it matters | Go + CUE | Other stacks |
|---|---|---|---|
| Single binary, zero runtime | Shipping a CLI to ops/DevOps that “just works” | go build produces a static binary that embeds CUE via cuelang.org/go |
Node, Python, etc. need a runtime and dependency tree |
| Schema ↔ code round-trip | Keep Go structs as the source-of-truth and still get CUE validation | cue get go k8s.io/api/apps/v1 auto-generates CUE from Go types; cue export can spit JSON/YAML back out |
Other languages have to hand-write schemas or use separate tools |
| Cloud-native lingua franca | Every major infra tool (K8s, Terraform, Helm, Docker, Dagger, Argo CD) is written in Go | You can import their Go packages and generate CUE constraints without re-implementing anything | Python/Node/Java must FFI or re-implement |
| Rich Go API | Load, unify, validate, diff, trim configs inside your program | Full lattice operations (unify, subsumption, export) via cuecontext and cue/load |
Only shell-out or WASM today for non-Go |
| Performance | Parse & validate 1000s of YAML manifests in CI | Pure Go, no CGO; benchmarks show ~2× faster than Starlark/Jsonnet on large k8s repos | Python/Node bindings pay serialization cost |
| Policy-as-code reuse | Embed the same constraints in admission webhooks, CLIs, or controllers | Import CUE in Go controller code; compile once, run everywhere | Rego (OPA) needs separate runtime; Jsonnet is turing-complete & slower |
| Community & tooling | KubeVela, Dagger, Grafana, Holos, etc. all expose Go SDKs that expect CUE | Shared libraries and examples | Smaller, fragmented ecosystems outside Go |
When not to pick Go + CUE
- Your service is purely browser/Node → TypeScript + JSON Schema or Zod is lighter.
- You need end-user scripting (e.g., Terraform custom providers) → HCL/Starlark still wins on mind-share.
- You target resource-constrained embedded → CUE’s Go runtime is heavier than a hand-rolled C validator.
TL;DR
If you are already in the Go / cloud-native orbit, Go + CUE is the only combination today that lets you keep your existing types, ship a single static CLI, and reuse the exact same constraints in controllers, CI, and documentation generators .