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