The Studio
The Studio is your authoring workspace for building and testing scenarios. It provides a live environment where you can design, configure, and validate your labs.
Accessing the Studio
From Tracks & Scenarios, you can:
- Click Open Studio to create a new scenario
- Click Open in Studio on an existing scenario
Studio Overview
┌─────────────────────────────────────────────────────────────┐
│ Logo Scenario Name ▼ [Run ▶] [Stop ■] [User ▼] │
├──────────────┬──────────────────────────────────────────────┤
│ │ │
│ Views │ │
│ ──────── │ Main Content Area │
│ Canvas │ │
│ Interfaces │ (changes based on selected view) │
│ Files │ │
│ Instructions│ │
│ Post-Deploy │ │
│ Variables │ │
│ Start Order │ │
│ Snapshots │ │
│ Secrets │ │
│ Details │ │
│ │ │
├──────────────┴──────────────────────────────────────────────┤
│ Status: Resources 1500m CPU / 2048Mi RAM | 3 components │
└─────────────────────────────────────────────────────────────┘Header Controls
| Element | Description |
|---|---|
| Scenario Name | Click to rename the scenario |
| Run | Start the studio environment to test |
| Stop | Stop the running environment |
| User Menu | Account settings, logout |
Studio Views
Canvas
The visual designer for your scenario's infrastructure.
Features:
- Drag and drop components
- Draw connections between components
- Select and configure components
- Pan and zoom the canvas
Canvas Toolbar:
| Button | Action |
|---|---|
| + Add | Open component catalog |
| Fit | Fit all components in view |
| Reset | Reset zoom and position |
Component Interactions:
- Click: Select component
- Double-click: Open configuration modal
- Drag: Move component
- Edge drag: Create connection
Interfaces
Access your running components' terminals and web UIs.
When the studio is running:
- Tabs appear for each component's configured interfaces
- Terminal tabs provide shell access
- Web UI tabs show HTTP interfaces
Files
Manage files embedded in your scenario.
Use Cases:
- Configuration files to mount in containers
- Sample data files
- Scripts to run
Instructions
Write and manage step-by-step guidance for participants.
Features:
- Add, edit, delete instructions
- Drag to reorder
- Markdown preview with syntax highlighting
- Tab navigation link testing
See Writing Instructions for details.
Post-Deploy
Configure scripts that run after components deploy.
Use Cases:
- Database initialization
- Sample data loading
- Configuration setup
Format:
#!/bin/bash
# Wait for service
until pg_isready; do sleep 1; done
# Initialize
psql -f /scripts/init.sqlVariables
Define variables that can be used in instructions, environment variables, files, and Helm values.
Features:
- Create named variables
- Values resolved at runtime
- Reference using
{{variable_name}}syntax
Built-in Runtime Variables:
| Variable | Description |
|---|---|
{{$namespace}} | Kubernetes namespace for this run |
{{$runId}} | Unique run identifier |
{{$scenarioId}} | Scenario identifier |
{{$self}} | Current component's service name |
{{$self:fqdn}} | Current component's internal FQDN |
{{$self:public}} | Current component's public hostname |
Component References:
| Pattern | Description | Example |
|---|---|---|
{{kafka}} | Internal service name | kafka |
{{kafka:fqdn}} | Internal FQDN | kafka.ns.svc.cluster.local |
{{kafka:public}} | Public hostname (ingress) | kafka-abc12345.vlab.io |
{{kafka:public:9092}} | Public hostname (validates port) | kafka-abc12345.vlab.io |
Secret References:
Reference secret values stored in the Secrets view:
| Pattern | Description |
|---|---|
{{secret:my-license:key}} | Value of key key from secret my-license |
{{secret:db-creds:password}} | Value of key password from secret db-creds |
Helm Service References:
For Helm components with multiple services:
| Pattern | Description |
|---|---|
{{kafka:broker}} | Service name from Helm metadata |
{{kafka:broker:fqdn}} | Service FQDN |
{{kafka:broker:public}} | Service public hostname |
Use Cases:
| Variable | Value | Use |
|---|---|---|
db_host | {{postgres}} | Internal connection |
public_url | {{$self:public}} | Kafka advertised listeners |
LICENSE_KEY | {{secret:license:key}} | Inject license from secret |
Start Order
Control the sequence in which components deploy.
Why Order Matters:
- Databases should start before apps
- Message brokers before producers
- Dependencies before dependents
Interface:
- Drag components to reorder
- Components with same order start in parallel
Snapshots
Capture and restore component state.
Creating Snapshots:
- Start the studio environment
- Configure your components as desired
- Go to Snapshots view
- Select components to include
- Add a comment and create
Using Snapshots:
- Activate a snapshot to restore state
- New runs start with snapshot state
- Great for pre-configured starting points
Secrets
Manage sensitive data for your scenario. Secrets are stored encrypted and can be referenced in environment variables, Helm values, and files.
Creating Secrets:
- Go to the Secrets view
- Click Add Secret
- Choose secret type:
- Opaque: Key-value pairs for generic secrets
- Docker Registry: Credentials for private container registries
- TLS: Certificate and private key
- Basic Auth: Username and password
Referencing Secrets in Templates:
Use the {{secret:name:key}} syntax to inject secret values:
# In environment variables
env:
LICENSE_KEY: "{{secret:my-license:key}}"
DB_PASSWORD: "{{secret:db-creds:password}}"
# In Helm values
auth:
password: "{{secret:postgres-auth:password}}"Examples:
| Secret Name | Key | Template | Use Case |
|---|---|---|---|
my-license | key | {{secret:my-license:key}} | Software license |
db-creds | password | {{secret:db-creds:password}} | Database password |
api-keys | stripe | {{secret:api-keys:stripe}} | API key |
TIP
Secret values are resolved at runtime when the component starts. The actual values are never exposed in the UI or logs.
Details
Edit scenario metadata:
| Field | Description |
|---|---|
| Name | Scenario display name |
| Description | What this scenario teaches |
| Default TTL | How long runs last |
Adding Components
From the Catalog
- Click + Add in the Canvas toolbar
- Browse or search components
- Click to add to canvas
- Position on canvas
Component Configuration
Double-click a component to configure:
General Tab:
- Label (identifier for tab links)
- Description
Resources Tab:
- CPU (millicores)
- Memory (MiB)
Environment Tab:
- Environment variables
- Format:
KEY=value
Secrets Tab:
- Sensitive values
- Stored encrypted
Tabs Tab:
- Configure terminal access
- Configure web UI access
Helm Values Tab: (Helm components)
- Override default values.yaml
Compose Tab: (Compose components)
- Edit docker-compose.yaml
Creating Connections
Connections visualize relationships between components.
To Create:
- Hover over a component edge
- Drag to another component
- Release to create connection
To Delete:
- Click on the connection line
- Press Delete or use context menu
INFO
Connections are purely visual—they don't affect deployment or networking.
Testing Your Scenario
Starting the Environment
- Click Run in the header
- Wait for components to provision
- Status bar shows progress
Using Interfaces
Once running:
- Switch to Interfaces view
- Click component tabs to access
- Test your instructions step-by-step
Verifying Instructions
- Go to Instructions view
- Click tab navigation links
- Verify they switch to correct tabs
- Copy code blocks and test commands
Stopping the Environment
Click Stop when finished. Resources are cleaned up automatically.
Auto-Save
The Studio auto-saves your work:
- Changes saved automatically
- No manual save required
- Status shown in header
Keyboard Shortcuts
| Shortcut | Action |
|---|---|
Delete | Delete selected component |
Escape | Deselect / Close modal |
Ctrl/Cmd + Z | Undo (canvas changes) |
Workflow Tips
Build Incrementally
- Add one component
- Configure and test
- Add next component
- Repeat
Test Early, Test Often
Don't wait until everything is built to test. Run the environment frequently to catch issues early.
Use Labels Consistently
Component labels appear in:
- Tab links in instructions
- Interface tabs
- Logs and debugging
Good labels: kafka, postgres, api Bad labels: component1, my-thing
Save Snapshots
Before major changes:
- Create a snapshot
- Make your changes
- If something breaks, restore
Troubleshooting
Component Won't Start
| Symptom | Cause | Solution |
|---|---|---|
Pending forever | Not enough resources | Reduce CPU/memory |
ImagePullBackOff | Image not found | Check image name |
CrashLoopBackOff | App crash | Check logs in terminal |
Terminal Won't Connect
| Issue | Check |
|---|---|
| "Pod not found" | Pod selector matches actual labels |
| "Container not found" | Container name is correct |
| Connection timeout | Pod is in Running state |
Web UI Shows Error
| Issue | Check |
|---|---|
| Blank page | Service is ready |
| Connection refused | Port number is correct |
| 404 error | Path is correct |
Instructions Don't Render
| Issue | Check |
|---|---|
| Raw markdown shown | Syntax is correct |
| Tab link not working | Component label matches |
| Code not highlighted | Language specified |
Next Steps
- Writing Instructions — Create engaging guidance
- Best Practices — Tips for effective scenarios
