Configuration
Global configuration, the option pattern, and how to customize Ctrl Plane behavior.
Ctrl Plane uses two complementary configuration mechanisms: a Config struct for static settings, and functional options for wiring dependencies.
Global config
The root ctrlplane.Config struct holds settings that affect the entire system:
type Config struct {
DatabaseURL string `json:"database_url" env:"CP_DATABASE_URL"`
DefaultProvider string `json:"default_provider" env:"CP_DEFAULT_PROVIDER"`
HealthInterval time.Duration `json:"health_interval" env:"CP_HEALTH_INTERVAL" default:"30s"`
TelemetryFlushInterval time.Duration `json:"telemetry_flush_interval" env:"CP_TELEMETRY_FLUSH" default:"10s"`
MaxInstancesPerTenant int `json:"max_instances_per_tenant" env:"CP_MAX_INSTANCES" default:"0"`
AuditEnabled bool `json:"audit_enabled" env:"CP_AUDIT_ENABLED" default:"true"`
}Each field has a json tag for file-based config, an env tag for environment variables, and a default tag where applicable.
Functional options
The app.CtrlPlane is configured with functional options passed to app.New(). Each option is a function that modifies the CtrlPlane during construction and can return an error if the configuration is invalid:
cp, err := app.New(
app.WithStore(postgresStore),
app.WithAuth(myAuthProvider),
app.WithProvider("k8s-prod", kubernetesProvider),
app.WithProvider("docker-dev", dockerProvider),
app.WithDefaultProvider("k8s-prod"),
app.WithEventBus(natsEventBus),
)Available options
| Option | Purpose |
|---|---|
WithConfig(cfg) | Set the global configuration struct |
WithStore(s) | Set the persistence backend |
WithAuth(p) | Set the authentication provider |
WithProvider(name, p) | Register a named cloud provider |
WithDefaultProvider(name) | Set which provider to use when none is specified |
WithEventBus(b) | Replace the default in-memory event bus |
Provider configuration
Each provider has its own Config struct. Here's the Docker provider as an example:
dockerProv, err := docker.New(docker.Config{
Host: "unix:///var/run/docker.sock",
Namespace: "ctrlplane",
DefaultCPU: 500,
DefaultMemory: 256,
NetworkName: "cp-network",
})Subsystem configuration
Individual subsystem services accept configuration through their constructors. When using app.New(), the wiring happens automatically. When using packages independently, you create services directly:
instanceSvc := instance.NewService(instance.ServiceConfig{
Store: myStore,
Provider: myProvider,
Events: myEventBus,
})File-based configuration (Forge extension)
When Ctrl Plane runs as a Forge extension, it can load configuration from the application's YAML config file. The extension checks two keys in order:
extensions.ctrlplane-- namespaced under the Forge extensions convention (recommended)ctrlplane-- legacy top-level key
extensions:
ctrlplane:
database_url: "postgres://localhost:5432/ctrlplane"
default_provider: "k8s"
base_path: "/ctrlplane"
health_interval: "30s"
telemetry_flush_interval: "10s"
max_instances_per_tenant: 100
audit_enabled: true
disable_routes: false
disable_migrate: falseExtension-specific fields
In addition to the global config fields, the extension config adds:
| Field | Type | Description | Default |
|---|---|---|---|
base_path | string | URL prefix for all ctrlplane routes | /ctrlplane |
disable_routes | bool | Disable automatic route registration | false |
disable_migrate | bool | Disable automatic database migration | false |
Configuration precedence
When both file-based and programmatic options are provided, they are merged:
- YAML values take precedence for string, duration, and integer fields.
- Programmatic boolean flags (
DisableRoutes,DisableMigrate) override when set totrue. AuthProvidercan only be set programmatically (not from YAML).- Any remaining zero-valued fields are filled from
DefaultConfig().
If no file-based config is found and RequireConfig is not set, the extension falls back to programmatic options merged with defaults.
Environment variables
All environment variables use the CP_ prefix to avoid collisions:
| Variable | Description | Default |
|---|---|---|
CP_DATABASE_URL | Database connection string | (none) |
CP_DEFAULT_PROVIDER | Default provider name | (none) |
CP_HEALTH_INTERVAL | Health check interval | 30s |
CP_TELEMETRY_FLUSH | Telemetry flush interval | 10s |
CP_MAX_INSTANCES | Max instances per tenant (0 = unlimited) | 0 |
CP_AUDIT_ENABLED | Enable audit logging | true |