CUE Language Overview
What is CUE?
CUE (Configure, Unify, Execute) is a configuration and data validation language designed to simplify tasks involving data validation, configuration, and data templating. It is particularly useful for defining and validating complex data structures, making it a powerful tool for managing configurations in a consistent and reliable manner.
Key Properties of CUE
CUE (Configure, Unify, Execute) is a powerful configuration language with several key properties that make it stand out:
-
Go-based General Purpose Configuration Language: CUE is built on Go, providing a robust foundation for configuration management.
-
Go-style Imports, Packages, and Modules: CUE adopts Go's approach to code organization, making it familiar for Go developers and promoting modularity.
-
Superset of JSON: Similar to JSONNET, CUE is a superset of JSON, allowing easy integration with existing JSON-based configurations.
-
Built-in Policy Assertions: CUE includes native support for defining and enforcing policies, enhancing configuration reliability and consistency.
-
Opinionated in the Right Places:
- Flexible with indentation, allowing developers to format their code for readability.
- Strict about:
- Separating scripting from configurations, promoting cleaner and more maintainable code.
- Ensuring finalized values are immutable, preventing accidental modifications.
-
Concise and Debuggable: CUE's syntax is designed to be concise yet expressive, making configurations easy to read, write, and debug.
These properties combine to make CUE a powerful tool for managing complex configurations while maintaining clarity and enforcing best practices.
Examples of CUE in Action
Schema and data validation
Schema and data validation
// Define a schema for a simple configuration
schema: {
name: string
age: int
email: string & =~"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
}
// Define a valid data instance that adheres to the schema
validData: schema & {
name: "John Doe"
age: 30
email: "[email protected]"
}
// Define an invalid data instance that does not adhere to the schema
invalidData: schema & {
name: "Jane Doe"
age: "thirty" // This will cause a validation error because age should be an int
email: "jane.doe@invalid-email" // This will cause a validation error because the email format is incorrect
}
Definitions, composition, definitions, and instances.
Definitions, schemas, validation and composition.
// Define a schema for server configuration
#ServerConfig: {
// Host can be either "localhost" or an IP address
host: "localhost" | string & =~"^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$"
// Port number, default is 8080
port: *8080 | int & >=1 & <=65535
// SSL configuration
ssl?: {
// SSL is disabled by default
enabled: *false | bool
// Key file path, required if SSL is enabled
keyFile?: string
// Cert file path, required if SSL is enabled
certFile?: string
}
}
// Define a schema for database configuration
#DatabaseConfig: {
// Database type, default is "mysql"
type: *"mysql" | "postgres" | "mongodb"
// Database host, default is "localhost"
host: *"localhost" | string
// Database port, default depends on the type
port: *{
mysql: 3306
postgres: 5432
mongodb: 27017
}[type] | int
// Username for database connection
username: string
// Password for database connection
password: string
// Database name
name: string
}
// Define a schema for feature configuration
#FeatureConfig: {
// Feature A is enabled by default
featureA: *true | bool
// Feature B is disabled by default
featureB: *false | bool
// Feature C has more complex configuration
featureC?: {
// Feature C is disabled by default
enabled: *false | bool
config?: {
param1: string
param2: string
}
}
}
// Complete configuration schema using composition
#Config: {
server: #ServerConfig
database: #DatabaseConfig
features: #FeatureConfig
}
// An instance of the configuration for my service
my_service_config: #Config & {
server: {
// Using default host and port
ssl: {
enabled: true
keyFile: "/path/to/keyfile"
certFile: "/path/to/certfile"
}
}
database: {
// Using default type (mysql) and host (localhost)
username: "root"
password: "password"
name: "mydatabase"
// Port will default to 3306 for mysql
}
features: {
// Using default for featureA (true) and featureB (false)
featureC: {
enabled: true
config: {
param1: "value1"
param2: "value2"
}
}
}
}
JSON vs CUE vs Yaml Configuration Example
To better understand the power of CUE, let's compare JSON configuration with its corresponding CUE and YAML configuration side by side. This example demonstrates how CUE can simplify and streamline configuration management.
- Concise, readable less cognitive load: No quotes around the keys compared to JSON, no commas
- Easy to understand, less error-prone: Curly braces for nested objects instead of hyphens like in YAML
- Easy to document: Comments are allowed like in YAML unlike JSON
JSON Configuration
- JSON Configuration
- CUE Configuration
- Yaml Configuration
{
"server": {
"host": "localhost",
"port": 8080,
"ssl": {
"enabled": true,
"keyFile": "/path/to/keyfile",
"certFile": "/path/to/certfile"
}
},
"database": {
"type": "mysql",
"host": "localhost",
"port": 3306,
"username": "root",
"password": "password",
"name": "mydatabase"
},
"features": {
"featureA": true,
"featureB": false,
"featureC": {
"enabled": true,
"config": {
"param1": "value1",
"param2": "value2"
}
}
}
}
server: {
host: "localhost"
port: 8080
ssl: {
enabled: true
keyFile: "/path/to/keyfile"
certFile: "/path/to/certfile"
}
}
database: {
type: "mysql"
host: "localhost"
port: 3306
username: "root"
password: "password"
name: "mydatabase"
}
features: {
featureA: true
featureB: false
featureC: {
enabled: true
config: {
param1: "value1"
param2: "value2"
}
}
}
// YAML equivalent
server:
host: localhost
port: 8080
ssl:
enabled: true
keyFile: /path/to/keyfile
certFile: /path/to/certfile
database:
type: mysql
host: localhost
port: 3306
username: root
password: password
name: mydatabase
features:
featureA: true
featureB: false
featureC:
enabled: true
config:
param1: value1
param2: value2