provisioning/docs/src/setup/workspace-setup.md
2026-01-17 03:58:28 +00:00

10 KiB

Workspace Setup

Create and initialize your first Provisioning workspace.

Overview

A workspace is the default organizational unit for all infrastructure work in Provisioning. It groups infrastructure definitions, configurations, extensions, and runtime data in an isolated environment.

Workspace Structure

Every workspace follows a consistent directory structure:

workspace_my_project/
├── config/                     # Workspace configuration
│   ├── workspace.ncl           # Workspace definition (Nickel)
│   ├── provisioning.yaml       # Workspace metadata
│   ├── dev-defaults.toml       # Development environment settings
│   ├── test-defaults.toml      # Testing environment settings
│   └── prod-defaults.toml      # Production environment settings
│
├── infra/                      # Infrastructure definitions
│   ├── servers.ncl             # Server configurations
│   ├── clusters.ncl            # Cluster definitions
│   ├── networks.ncl            # Network configurations
│   └── batch-workflows.ncl     # Batch workflow definitions
│
├── extensions/                 # Workspace-specific extensions (optional)
│   ├── providers/              # Custom providers
│   ├── taskservs/              # Custom task services
│   ├── clusters/               # Custom cluster templates
│   └── workflows/              # Custom workflow definitions
│
└── runtime/                    # Runtime data (gitignored)
    ├── state/                  # Infrastructure state files
    ├── checkpoints/            # Workflow checkpoints
    ├── logs/                   # Operation logs
    └── generated/              # Generated configuration files

Creating a Workspace

Method 1: From Built-in Template

# Create from default template
provisioning workspace init my-project

# Create from specific template
provisioning workspace init my-k8s --template kubernetes-ha

# Create with custom path
provisioning workspace init my-project --path /custom/location

Method 2: From Git Repository

# Clone infrastructure repository
git clone  [https://github.com/org/infra-repo.git](https://github.com/org/infra-repo.git) my-infra
cd my-infra

# Import as workspace
provisioning workspace init . --import

Available Templates

Provisioning includes templates for common use cases:

Template Description Use Case
default Minimal structure General-purpose infrastructure
kubernetes-ha HA Kubernetes (3 control planes) Production Kubernetes deployments
development Dev-optimized with Docker Compose Local testing and development
multi-cloud Multiple provider configs Multi-cloud deployments
database-cluster Database-focused Database infrastructure
cicd CI/CD pipeline configs Automated deployment pipelines

List available templates:

provisioning workspace templates

# Show template details
provisioning workspace template show kubernetes-ha

Switching Workspaces

List All Workspaces

provisioning workspace list

# Example output:
NAME              PATH                           LAST_USED          STATUS
my-project        ~/.provisioning/workspace_my   2026-01-16 10:30   Active
dev-env           ~/.provisioning/workspace_dev  2026-01-15 15:45
production        ~/.provisioning/workspace_prod 2026-01-10 09:00

Switch to a Workspace

# Switch workspace
provisioning workspace switch my-project

# Verify switch
provisioning workspace status

# Quick switch (shortcut)
provisioning ws switch dev-env

When you switch workspaces:

  • Active workspace marker updates in user configuration
  • Environment variables update for current session
  • CLI prompt changes (if configured)
  • Last-used timestamp updates

Workspace Registry

The workspace registry is stored in user configuration:

# ~/.config/provisioning/user_config.yaml
workspaces:
  active: my-project
  registry:
    my-project:
      path: ~/.provisioning/workspaces/workspace_my_project
      created: 2026-01-16T10:30:00Z
      last_used: 2026-01-16T14:20:00Z
      template: default

Configuring Workspace

Workspace Definition (workspace.ncl)

# workspace.ncl - Workspace configuration

{
  # Workspace metadata
  name = "my-project"
  description = "My infrastructure project"
  version = "1.0.0"

  # Environment settings
  environment = 'production

  # Default provider
  provider = "upcloud"

  # Region preferences
  region = "de-fra1"

  # Workspace-specific providers (override defaults)
  providers = {
    upcloud = {
      endpoint = " [https://api.upcloud.com"](https://api.upcloud.com")
      region = "de-fra1"
    }
    aws = {
      region = "us-east-1"
    }
  }

  # Extensions (inherit from provisioning/extensions/)
  extensions = {
    providers = ["upcloud", "aws"]
    taskservs = ["kubernetes", "docker", "postgres"]
    clusters = ["web", "oci-reg"]
  }
}

Environment-Specific Configuration

Create environment-specific configuration files:

# Development environment
config/dev-defaults.toml:
[server]
plan = "small"
backup_enabled = false

# Production environment
config/prod-defaults.toml:
[server]
plan = "large"
backup_enabled = true
monitoring_enabled = true

Use environment selection:

# Deploy to development
PROVISIONING_ENV=dev provisioning server create

# Deploy to production (stricter validation)
PROVISIONING_ENV=prod provisioning server create --validate

Workspace Metadata (provisioning.yaml)

name: "my-project"
version: "1.0.0"
created: "2026-01-16T10:30:00Z"
owner: "team-infra"

# Provider configuration
providers:
  default: "upcloud"
  upcloud:
    api_endpoint: " [https://api.upcloud.com"](https://api.upcloud.com")
    region: "de-fra1"
  aws:
    region: "us-east-1"

# Workspace features
features:
  workspace_switching: true
  batch_workflows: true
  test_environment: true
  security_system: true

# Validation rules
validation:
  strict: true
  check_dependencies: true
  validate_certificates: true

# Backup settings
backup:
  enabled: true
  frequency: "daily"
  retention_days: 30

Initializing Infrastructure

Step 1: Create Infrastructure Definition

Create infra/servers.ncl:

let defaults = import "defaults.ncl" in

{
  servers = [
    defaults.make_server {
      name = "web-01"
      plan = "medium"
      region = "de-fra1"
    }
    defaults.make_server {
      name = "db-01"
      plan = "large"
      region = "de-fra1"
      backup_enabled = true
    }
  ]
}

Step 2: Validate Configuration

# Validate Nickel configuration
nickel typecheck infra/servers.ncl

# Export and validate
nickel export infra/servers.ncl | provisioning validate config

# Verbose validation
provisioning validate config --verbose

Step 3: Export Configuration

# Export Nickel to TOML (generated output)
nickel export --format toml infra/servers.ncl > infra/servers.toml

# The .toml files are auto-generated, don't edit directly

Workspace Security

Securing Credentials

Credentials are encrypted with SOPS + Age:

# Initialize secrets
provisioning sops init

# Create encrypted secrets file
provisioning sops create .secrets/providers.enc.yaml

# Encrypt existing credentials
sops -e -i infra/credentials.toml

Git Workflow

Version control best practices:

# COMMIT (shared with team)
infra/**/*.ncl              # Infrastructure definitions
config/*.toml               # Environment configurations
config/provisioning.yaml    # Workspace metadata
extensions/**/*             # Custom extensions

# GITIGNORE (never commit)
config/local-overrides.toml # Local user settings
runtime/**/*                # Runtime data and state
**/*.secret                 # Credential files
**/*.enc                    # Encrypted files (if not decrypted locally)

Multi-Workspace Strategies

Strategy 1: Separate Workspaces Per Environment

# Create dedicated workspaces
provisioning workspace init myapp-dev
provisioning workspace init myapp-staging
provisioning workspace init myapp-prod

# Each workspace is completely isolated
provisioning ws switch myapp-prod
provisioning server create  # Creates in prod only

Pros: Complete isolation, different credentials, independent state Cons: More workspace management, configuration duplication

Strategy 2: Single Workspace, Multiple Environments

# Single workspace with environment configs
provisioning workspace init myapp

# Deploy to different environments
PROVISIONING_ENV=dev provisioning server create
PROVISIONING_ENV=staging provisioning server create
PROVISIONING_ENV=prod provisioning server create

Pros: Shared configuration, easier maintenance Cons: Shared credentials, risk of cross-environment mistakes

Strategy 3: Hybrid Approach

# Dev workspace for experimentation
provisioning workspace init myapp-dev

# Prod workspace for production only
provisioning workspace init myapp-prod

# Use environment flags within workspaces
provisioning ws switch myapp-prod
PROVISIONING_ENV=prod provisioning cluster deploy

Pros: Balances isolation and convenience Cons: More complex to explain to teams

Workspace Validation

Before deploying infrastructure:

# Validate entire workspace
provisioning validate workspace

# Validate specific configuration
provisioning validate config --infra servers.ncl

# Validate with strict rules
provisioning validate config --strict

Troubleshooting

Workspace Not Found

# Re-register workspace
provisioning workspace register /path/to/workspace

# Or create new workspace
provisioning workspace init my-project

Permission Errors

# Fix workspace permissions
chmod 755 ~/.provisioning/workspaces/workspace_*
chmod 644 ~/.provisioning/workspaces/workspace_*/config/*

Configuration Validation Errors

# Check configuration syntax
nickel typecheck infra/*.ncl

# Inspect generated TOML
nickel export infra/*.ncl | jq '.'

# Debug configuration loading
provisioning config validate --verbose

Next Steps

  1. Configure infrastructure
  2. Deploy servers
  3. Create batch workflows