Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Workspace Configuration Architecture

Version: 2.0.0 Date: 2025-10-06 Status: Implemented

Overview

The provisioning system now uses a workspace-based configuration architecture where each workspace has its own complete configuration structure. This replaces the old ENV-based and template-only system.

Critical Design Principle

config.defaults.toml is ONLY a template, NEVER loaded at runtime

This file exists solely as a reference template for generating workspace configurations. The system does NOT load it during operation.

Configuration Hierarchy

Configuration is loaded in the following order (lowest to highest priority):

  1. Workspace Config (Base): {workspace}/config/provisioning.yaml
  2. Provider Configs: {workspace}/config/providers/*.toml
  3. Platform Configs: {workspace}/config/platform/*.toml
  4. User Context: ~/Library/Application Support/provisioning/ws_{name}.yaml
  5. Environment Variables: PROVISIONING_* (highest priority)

Workspace Structure

When a workspace is initialized, the following structure is created:

{workspace}/
├── config/
│   ├── provisioning.yaml       # Main workspace config (generated from template)
│   ├── providers/              # Provider-specific configs
│   │   ├── aws.toml
│   │   ├── local.toml
│   │   └── upcloud.toml
│   ├── platform/               # Platform service configs
│   │   ├── orchestrator.toml
│   │   └── mcp.toml
│   └── kms.toml                # KMS configuration
├── infra/                      # Infrastructure definitions
├── .cache/                     # Cache directory
├── .runtime/                   # Runtime data
│   ├── taskservs/
│   └── clusters/
├── .providers/                 # Provider state
├── .kms/                       # Key management
│   └── keys/
├── generated/                  # Generated files
└── .gitignore                  # Workspace gitignore

Template System

Templates are located at: /Users/Akasha/project-provisioning/provisioning/config/templates/

Available Templates

  1. workspace-provisioning.yaml.template - Main workspace configuration
  2. provider-aws.toml.template - AWS provider configuration
  3. provider-local.toml.template - Local provider configuration
  4. provider-upcloud.toml.template - UpCloud provider configuration
  5. kms.toml.template - KMS configuration
  6. user-context.yaml.template - User context configuration

Template Variables

Templates support the following interpolation variables:

  • {{workspace.name}} - Workspace name
  • {{workspace.path}} - Absolute path to workspace
  • {{now.iso}} - Current timestamp in ISO format
  • {{env.HOME}} - User’s home directory
  • {{env.*}} - Environment variables (safe list only)
  • {{paths.base}} - Base path (after config load)

Workspace Initialization

Command

# Using the workspace init function
nu -c "use provisioning/core/nulib/lib_provisioning/workspace/init.nu *; workspace-init 'my-workspace' '/path/to/workspace' --providers ['aws' 'local'] --activate"

Process

  1. Create Directory Structure: All necessary directories
  2. Generate Config from Template: Creates config/provisioning.yaml
  3. Generate Provider Configs: For each specified provider
  4. Generate KMS Config: Security configuration
  5. Create User Context (if –activate): User-specific overrides
  6. Create .gitignore: Ignore runtime/cache files

User Context

User context files are stored per workspace:

Location: ~/Library/Application Support/provisioning/ws_{workspace_name}.yaml

Purpose

  • Store user-specific overrides (debug settings, output preferences)
  • Mark active workspace
  • Override workspace paths if needed

Example

workspace:
  name: "my-workspace"
  path: "/path/to/my-workspace"
  active: true

debug:
  enabled: true
  log_level: "debug"

output:
  format: "json"

providers:
  default: "aws"

Configuration Loading Process

1. Determine Active Workspace

# Check user config directory for active workspace
let user_config_dir = ~/Library/Application Support/provisioning/
let active_workspace = (find workspace with active: true in ws_*.yaml files)

2. Load Workspace Config

# Load main workspace config
let workspace_config = {workspace.path}/config/provisioning.yaml

3. Load Provider Configs

# Merge all provider configs
for provider in {workspace.path}/config/providers/*.toml {
  merge provider config
}

4. Load Platform Configs

# Merge all platform configs
for platform in {workspace.path}/config/platform/*.toml {
  merge platform config
}

5. Apply User Context

# Apply user-specific overrides
let user_context = ~/Library/Application Support/provisioning/ws_{name}.yaml
merge user_context (highest config priority)

6. Apply Environment Variables

# Final overrides from environment
PROVISIONING_DEBUG=true
PROVISIONING_LOG_LEVEL=debug
PROVISIONING_PROVIDER=aws
# etc.

Migration from Old System

Before (ENV-based)

export PROVISIONING=/usr/local/provisioning
export PROVISIONING_INFRA_PATH=/path/to/infra
export PROVISIONING_DEBUG=true
# ... many ENV variables

After (Workspace-based)

# Initialize workspace
workspace-init "production" "/workspaces/prod" --providers ["aws"] --activate

# All config is now in workspace
# No ENV variables needed (except for overrides)

Breaking Changes

  1. config.defaults.toml NOT loaded - Only used as template
  2. Workspace required - Must have active workspace or be in workspace directory
  3. New config locations - User config in ~/Library/Application Support/provisioning/
  4. YAML main config - provisioning.yaml instead of TOML

Workspace Management Commands

Initialize Workspace

use provisioning/core/nulib/lib_provisioning/workspace/init.nu *
workspace-init "my-workspace" "/path/to/workspace" --providers ["aws" "local"] --activate

List Workspaces

workspace-list

Activate Workspace

workspace-activate "my-workspace"

Get Active Workspace

workspace-get-active

Implementation Files

Core Files

  1. Template Directory: /Users/Akasha/project-provisioning/provisioning/config/templates/
  2. Workspace Init: /Users/Akasha/project-provisioning/provisioning/core/nulib/lib_provisioning/workspace/init.nu
  3. Config Loader: /Users/Akasha/project-provisioning/provisioning/core/nulib/lib_provisioning/config/loader.nu

Key Changes in Config Loader

Removed

  • get-defaults-config-path() - No longer loads config.defaults.toml
  • Old hierarchy with user/project/infra TOML files

Added

  • get-active-workspace() - Finds active workspace from user config
  • Support for YAML config files
  • Provider and platform config merging
  • User context loading

Configuration Schema

Main Workspace Config (provisioning.yaml)

workspace:
  name: string
  version: string
  created: timestamp

paths:
  base: string
  infra: string
  cache: string
  runtime: string
  # ... all paths

core:
  version: string
  name: string

debug:
  enabled: bool
  log_level: string
  # ... debug settings

providers:
  active: [string]
  default: string

# ... all other sections

Provider Config (providers/*.toml)

[provider]
name = "aws"
enabled = true
workspace = "workspace-name"

[provider.auth]
profile = "default"
region = "us-east-1"

[provider.paths]
base = "{workspace}/.providers/aws"
cache = "{workspace}/.providers/aws/cache"

User Context (ws_{name}.yaml)

workspace:
  name: string
  path: string
  active: bool

debug:
  enabled: bool
  log_level: string

output:
  format: string

Benefits

  1. No Template Loading: config.defaults.toml is template-only
  2. Workspace Isolation: Each workspace is self-contained
  3. Explicit Configuration: No hidden defaults from ENV
  4. Clear Hierarchy: Predictable override behavior
  5. Multi-Workspace Support: Easy switching between workspaces
  6. User Overrides: Per-workspace user preferences
  7. Version Control: Workspace configs can be committed (except secrets)

Security Considerations

Generated .gitignore

The workspace .gitignore excludes:

  • .cache/ - Cache files
  • .runtime/ - Runtime data
  • .providers/ - Provider state
  • .kms/keys/ - Secret keys
  • generated/ - Generated files
  • *.log - Log files

Secret Management

  • KMS keys stored in .kms/keys/ (gitignored)
  • SOPS config references keys, doesn’t store them
  • Provider credentials in user-specific locations (not workspace)

Troubleshooting

No Active Workspace Error

Error: No active workspace found. Please initialize or activate a workspace.

Solution: Initialize or activate a workspace:

workspace-init "my-workspace" "/path/to/workspace" --activate

Config File Not Found

Error: Required configuration file not found: {workspace}/config/provisioning.yaml

Solution: The workspace config is corrupted or deleted. Re-initialize:

workspace-init "workspace-name" "/existing/path" --providers ["aws"]

Provider Not Configured

Solution: Add provider config to workspace:

# Generate provider config manually
generate-provider-config "/workspace/path" "workspace-name" "aws"

Future Enhancements

  1. Workspace Templates: Pre-configured workspace templates (dev, prod, test)
  2. Workspace Import/Export: Share workspace configurations
  3. Remote Workspace: Load workspace from remote Git repository
  4. Workspace Validation: Comprehensive workspace health checks
  5. Config Migration Tool: Automated migration from old ENV-based system

Summary

  • config.defaults.toml is ONLY a template - Never loaded at runtime
  • Workspaces are self-contained - Complete config structure generated from templates
  • New hierarchy: Workspace → Provider → Platform → User Context → ENV
  • User context for overrides - Stored in ~/Library/Application Support/provisioning/
  • Clear, explicit configuration - No hidden defaults
  • Template files: provisioning/config/templates/
  • Workspace init: provisioning/core/nulib/lib_provisioning/workspace/init.nu
  • Config loader: provisioning/core/nulib/lib_provisioning/config/loader.nu
  • User guide: docs/user/workspace-management.md