Creating Labs

Creating Tasks

Learn how to create task directories, write assignment instructions, and configure tabs for POV Demo labs.

Task Directory Structure

Each task is a directory inside the lab root with at least two characters whose name begins with a digit. Tasks are read in directory-name order; use zero-padded prefixes such as 01- to make that order clear.

01-exploring-pods/
├── assignment.md        # Task instructions with YAML frontmatter
├── setup-ubuntu-1       # Runs before learner starts the task
├── check-ubuntu-1       # Validates learner's work (exit 0 = pass)
└── solve-ubuntu-1       # Provides the solution
  • Recommended: use two-digit numeric prefixes such as 01-, 02-, and 03-.
  • The name after the prefix is descriptive but not shown to learners — only the title in frontmatter is displayed
  • For labs with VMs, script files use {operation}-{vm-name} (for example, check-ubuntu-1).

assignment.md Format

The assignment.md file has two parts: a YAML frontmatter block (between --- delimiters) and the task content in Markdown.

---
slug: "explore-pods"
id: "explore-pods"
type: "challenge"
title: "Explore Running Pods"
teaser: "Use kubectl to inspect pods in a running cluster."
notes:
  - type: text
    contents: |
      Kubernetes Pods are the smallest deployable units. In this task,
      you will explore pods running in your cluster.
tabs:
  - title: "Terminal"
    type: terminal
    hostname: ubuntu-1
  - title: "Kubernetes Dashboard"
    type: service
    id: "kubernetes-dashboard"
    hostname: ubuntu-1
    port: 8001
difficulty: "basic"
skip: false
---

List all pods in the default namespace:

```bash
kubectl get pods
```

You should see the pods created by the lab setup script. Note the STATUS column — all pods should show `Running`.

Describe one of the pods to see its details:

```bash
kubectl describe pod <pod-name>
```
Authoring guidance: Avoid repeating the task title as an H1 (# Title) in the Markdown content. The platform can render the title field separately.

Frontmatter Fields

The bundle parses these fields and requires delimited frontmatter when it builds a task. For ordinary labs, pov validate silently skips absent or unterminated frontmatter; when it can parse delimited YAML, it rejects service tabs without a valid id. Puzzle labs add their own constraints.

FieldEnforced by validateDescription
slugNoTask slug stored in the published task.
idNoTask ID. The bundle uses the directory name when this is omitted.
typeNoTask type stored in the published task.
titleNoDisplayed task title.
teaserNoShort task description.
notesNoContext blocks with type and contents.
difficultyNoAccepted task difficulty metadata.
enhanced_loadingNoAccepted task loading metadata.
tabsNoUI tab configuration. Service tabs require a URL-safe id when validated locally.
timelimitNoTask time value. A positive value is required only for the single task in a puzzle lab.
skipNoPublished task metadata; local validation does not enforce skip behavior.

Tab Types

TypeRequired FieldsDescription
terminalhostnameOpens a terminal connected to the specified VM.
serviceid, hostname, portOpens a web service running on the VM at the given port. Local validation requires id to be lowercase alphanumeric/hyphen and not begin or end with a hyphen; other routing fields are optional to that validator.
codehostname, pathOpens a file editor for the given path on the VM.
aws_credentialsShows temporary AWS credentials and opens the AWS Console for the lab session.
gcp_credentialsShows temporary GCP credentials and opens the GCP Console for the lab session.
azure_credentialsShows temporary Azure credentials and opens the Azure Portal for the lab session.
# Terminal tab
- title: "Server Terminal"
  type: terminal
  hostname: ubuntu-1

# Service tab
- title: "Dashboard"
  type: service
  id: dashboard
  hostname: ubuntu-1
  port: 8080

# Code editor tab
- title: "Config File"
  type: code
  hostname: ubuntu-1
  path: /etc/myapp/config.yaml

# AWS credentials tab
- title: "AWS Console"
  type: aws_credentials

# GCP credentials tab
- title: "GCP Console"
  type: gcp_credentials

# Azure credentials tab
- title: "Azure Portal"
  type: azure_credentials
Authoring guidance: Reference the tab title when instructions require a context switch (for example, “Click the Terminal tab”).

Keep Tasks Focused

Aim for a small, coherent set of steps. Split a task when learners need to hold too much context at once; this is authoring guidance, not a validator rule.

Avoid

One task with 8 steps: “Complete Kubernetes Setup”

  • Install kubectl
  • Configure kubeconfig
  • Create a namespace
  • Deploy an application
  • Expose a service
  • Verify the deployment
  • Scale the deployment
  • Check logs

Correct

Split into three focused tasks:

Task 1 (3 steps)

  • Install kubectl
  • Configure kubeconfig
  • Verify connectivity

Task 2 (3 steps)

  • Create a namespace
  • Deploy an application
  • Verify the deployment

Task 3 (3 steps)

  • Expose a service
  • Scale the deployment
  • Check logs