# 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:

```bash
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

```bash
# 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

```bash
# 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:

```bash
provisioning workspace templates

# Show template details
provisioning workspace template show kubernetes-ha
```

## Switching Workspaces

### List All Workspaces

```bash
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

```bash
# 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:

```yaml
# ~/.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)

```nickel
# 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:

```bash
# 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:

```bash
# 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)

```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`:

```nickel
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

```bash
# 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

```bash
# 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:

```bash
# 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:

```bash
# 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

```bash
# 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

```bash
# 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

```bash
# 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:

```bash
# 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

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

# Or create new workspace
provisioning workspace init my-project
```

### Permission Errors

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

### Configuration Validation Errors

```bash
# 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](configuration.md)
2. [Deploy servers](../guides/from-scratch.md)
3. [Create batch workflows](../infrastructure/batch-workflows.md)
