Task
The task resource defines interactive activities that users must complete during a lab. Tasks can include multiple conditions with validation scripts, setup procedures, and solution scripts. Tasks are embedded in instruction pages and provide automated checking of user progress.
Use Cases
Section titled “Use Cases”As a lab author, you use tasks to create hands-on learning experiences with automated validation:
- Skill Validation: Create practical exercises that verify users can perform specific technical tasks correctly
- Progressive Learning: Build sequences of tasks that gradually increase in complexity to scaffold learning
- Granular Feedback: Break complex tasks into smaller conditions with individual lifecycle scripts for clearer guidance
Tasks transform passive instruction into active learning experiences where users practice real-world skills with immediate validation and guidance.
HCL Syntax
Section titled “HCL Syntax”Basic Syntax
Section titled “Basic Syntax”resource "task" "create_file" { description = "Create a file in the home directory"
config { target = resource.container.ubuntu }
condition "create_file" { description = "Create /tmp/hello.txt"
check { script = "scripts/task/create_file/check_file.sh" } }}Full Syntax
Section titled “Full Syntax”resource "task" "docker_setup" { description = "Complete the Docker setup" success_message = "Excellent! You've completed all requirements."
config { target = resource.container.ubuntu user = "root" group = "root" working_directory = "/home/user" timeout = "30s" environment = { PATH = "/usr/local/bin:/usr/bin:/bin" } success_exit_codes = [0] failure_exit_codes = [1, 2]
parallel_exec { condition = true check = false solve = false setup = false cleanup = false } }
condition "setup_environment" { description = "Set up the Docker environment"
config { timeout = "60s" }
setup { script = "scripts/task/docker_setup/setup_docker.sh" }
check { script = "scripts/task/docker_setup/check_docker.sh" failure_message = "Docker is not running correctly" }
solve { script = "scripts/task/docker_setup/solve_docker.sh" }
cleanup { script = "scripts/task/docker_setup/cleanup_docker.sh" } }
condition "create_container" { description = "Create and run a container"
check { script = "scripts/task/docker_setup/check_container.sh"
config { timeout = "45s" } }
solve { script = "scripts/task/docker_setup/solve_container.sh" } }}Resource Structure
Section titled “Resource Structure”task├─ description (required)├─ success_message (optional metadata)├─ config (default configuration for all scripts)│ ├─ target, user, group, working_directory│ ├─ timeout, environment│ ├─ success_exit_codes, failure_exit_codes│ └─ parallel_exec│ └─ condition, check, solve, setup, cleanup└─ conditions[] (one or more required) ├─ id (label), description (required) ├─ config (inherits from task config, can override) └─ script blocks (multiple of each type allowed) ├─ setup[] (runs when condition starts) ├─ check[] (runs during validation) ├─ solve[] (runs when skipped) └─ cleanup[] (runs when condition completes) └─ each script: script path, failure_message, config overrideFields
| Field | Type | Required | Description |
|---|---|---|---|
description | string | ✓ | Add a short explanation of what users are expected to achieve. |
prerequisites | list(reference)chapter, task, quiz | — | Tasks that must complete before this task can start |
success_ | string | — | A message shown to learners when they complete the task correctly. Use it to confirm success or provide a next step. |
config | block | — | Default execution context for all conditions |
condition | block | — | Validation conditions that must all pass for task completionrepeatable |
Configuration
Default execution context for all conditions
| Field | Type | Required | Description |
|---|---|---|---|
target | referencecontainer, vm | — | Select the sandbox component where this task will run. The task executes commands inside the chosen environment. |
user | string | — | Set the user or group identity under which the task runs inside the container. This helps control permissions. |
group | string | — | Set the user or group identity under which the task runs inside the container. This helps control permissions. |
working_ | string | — | Specify the directory path where the task commands will execute. Leave empty to use the default working directory. |
environment | map(string) | — | Environment variables for script execution |
timeout | string | — | Set how long the task can run before it stops automatically. Use this to prevent tasks from hanging indefinitely. ConstraintsMust be a valid duration (e.g. 30s, 5m) |
success_ | list(number) | — | Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. |
failure_ | list(number) | — | Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. |
parallel_ | block | — | Configure parallel execution for lifecycle scripts |
Parallel Exec
Configure parallel execution for lifecycle scripts
| Field | Type | Required | Description |
|---|---|---|---|
condition | bool | — | Execute all condition blocks in parallel Default false |
check | bool | — | Execute all check scripts in parallel within a condition Default false |
solve | bool | — | Execute all solve scripts in parallel within a condition Default false |
setup | bool | — | Execute all setup scripts in parallel within a condition Default false |
cleanup | bool | — | Execute all cleanup scripts in parallel within a condition Default false |
Condition
Validation conditions that must all pass for task completion
| Field | Type | Required | Description |
|---|---|---|---|
id | label | ✓ | An internal identifier for the condition. Used to reference this condition within the task configuration. Not visible to learners. |
description | string | ✓ | Explain what this condition checks or validates for the learner. Keep it short and action-oriented so users understand what success means. |
config | block | — | Use this to override task-level settings for this specific condition. Common overrides include timeout, working directory, or user permissions. |
check | block | — | Validation scripts to verify task completion (required)repeatable |
solve | block | — | Scripts to automatically solve this conditionrepeatable |
setup | block | — | Scripts to run before checks startrepeatable |
cleanup | block | — | Scripts to run after task completes (success or failure)repeatable |
Configuration
Execution context override for this condition
| Field | Type | Required | Description |
|---|---|---|---|
target | referencecontainer, vm | — | Select the sandbox component where this task will run. The task executes commands inside the chosen environment. |
user | string | — | Set the user or group identity under which the task runs inside the container. This helps control permissions. |
group | string | — | Set the user or group identity under which the task runs inside the container. This helps control permissions. |
working_ | string | — | Specify the directory path where the task commands will execute. Leave empty to use the default working directory. |
environment | map(string) | — | Environment variables for script execution |
timeout | string | — | Set how long the task can run before it stops automatically. Use this to prevent tasks from hanging indefinitely. ConstraintsMust be a valid duration (e.g. 30s, 5m) |
success_ | list(number) | — | Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. |
failure_ | list(number) | — | Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. |
parallel_ | block | — | Configure parallel execution for lifecycle scripts |
Parallel Exec
Configure parallel execution for lifecycle scripts
| Field | Type | Required | Description |
|---|---|---|---|
condition | bool | — | Execute all condition blocks in parallel Default false |
check | bool | — | Execute all check scripts in parallel within a condition Default false |
solve | bool | — | Execute all solve scripts in parallel within a condition Default false |
setup | bool | — | Execute all setup scripts in parallel within a condition Default false |
cleanup | bool | — | Execute all cleanup scripts in parallel within a condition Default false |
Check
Validation scripts to verify task completion (required)
| Field | Type | Required | Description |
|---|---|---|---|
script | string | — | The file location of the script to execute ConstraintsMust be a script file (.sh, .bash, .py, .rb, .js) |
failure_ | string | — | The message to show if the check has failed |
config | block | — | Execution context override for this script |
Configuration
Execution context override for this script
| Field | Type | Required | Description |
|---|---|---|---|
target | referencecontainer, vm | — | Select the sandbox component where this task will run. The task executes commands inside the chosen environment. |
user | string | — | Set the user or group identity under which the task runs inside the container. This helps control permissions. |
group | string | — | Set the user or group identity under which the task runs inside the container. This helps control permissions. |
working_ | string | — | Specify the directory path where the task commands will execute. Leave empty to use the default working directory. |
environment | map(string) | — | Environment variables for script execution |
timeout | string | — | Set how long the task can run before it stops automatically. Use this to prevent tasks from hanging indefinitely. ConstraintsMust be a valid duration (e.g. 30s, 5m) |
success_ | list(number) | — | Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. |
failure_ | list(number) | — | Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. |
parallel_ | block | — | Configure parallel execution for lifecycle scripts |
Parallel Exec
Configure parallel execution for lifecycle scripts
| Field | Type | Required | Description |
|---|---|---|---|
condition | bool | — | Execute all condition blocks in parallel Default false |
check | bool | — | Execute all check scripts in parallel within a condition Default false |
solve | bool | — | Execute all solve scripts in parallel within a condition Default false |
setup | bool | — | Execute all setup scripts in parallel within a condition Default false |
cleanup | bool | — | Execute all cleanup scripts in parallel within a condition Default false |
Solve
Scripts to automatically solve this condition
| Field | Type | Required | Description |
|---|---|---|---|
script | string | — | The file location of the script to execute ConstraintsMust be a script file (.sh, .bash, .py, .rb, .js) |
failure_ | string | — | The message to show if the check has failed |
config | block | — | Execution context override for this script |
Configuration
Execution context override for this script
| Field | Type | Required | Description |
|---|---|---|---|
target | referencecontainer, vm | — | Select the sandbox component where this task will run. The task executes commands inside the chosen environment. |
user | string | — | Set the user or group identity under which the task runs inside the container. This helps control permissions. |
group | string | — | Set the user or group identity under which the task runs inside the container. This helps control permissions. |
working_ | string | — | Specify the directory path where the task commands will execute. Leave empty to use the default working directory. |
environment | map(string) | — | Environment variables for script execution |
timeout | string | — | Set how long the task can run before it stops automatically. Use this to prevent tasks from hanging indefinitely. ConstraintsMust be a valid duration (e.g. 30s, 5m) |
success_ | list(number) | — | Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. |
failure_ | list(number) | — | Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. |
parallel_ | block | — | Configure parallel execution for lifecycle scripts |
Parallel Exec
Configure parallel execution for lifecycle scripts
| Field | Type | Required | Description |
|---|---|---|---|
condition | bool | — | Execute all condition blocks in parallel Default false |
check | bool | — | Execute all check scripts in parallel within a condition Default false |
solve | bool | — | Execute all solve scripts in parallel within a condition Default false |
setup | bool | — | Execute all setup scripts in parallel within a condition Default false |
cleanup | bool | — | Execute all cleanup scripts in parallel within a condition Default false |
Setup
Scripts to run before checks start
| Field | Type | Required | Description |
|---|---|---|---|
script | string | — | The file location of the script to execute ConstraintsMust be a script file (.sh, .bash, .py, .rb, .js) |
failure_ | string | — | The message to show if the check has failed |
config | block | — | Execution context override for this script |
Configuration
Execution context override for this script
| Field | Type | Required | Description |
|---|---|---|---|
target | referencecontainer, vm | — | Select the sandbox component where this task will run. The task executes commands inside the chosen environment. |
user | string | — | Set the user or group identity under which the task runs inside the container. This helps control permissions. |
group | string | — | Set the user or group identity under which the task runs inside the container. This helps control permissions. |
working_ | string | — | Specify the directory path where the task commands will execute. Leave empty to use the default working directory. |
environment | map(string) | — | Environment variables for script execution |
timeout | string | — | Set how long the task can run before it stops automatically. Use this to prevent tasks from hanging indefinitely. ConstraintsMust be a valid duration (e.g. 30s, 5m) |
success_ | list(number) | — | Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. |
failure_ | list(number) | — | Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. |
parallel_ | block | — | Configure parallel execution for lifecycle scripts |
Parallel Exec
Configure parallel execution for lifecycle scripts
| Field | Type | Required | Description |
|---|---|---|---|
condition | bool | — | Execute all condition blocks in parallel Default false |
check | bool | — | Execute all check scripts in parallel within a condition Default false |
solve | bool | — | Execute all solve scripts in parallel within a condition Default false |
setup | bool | — | Execute all setup scripts in parallel within a condition Default false |
cleanup | bool | — | Execute all cleanup scripts in parallel within a condition Default false |
Cleanup
Scripts to run after task completes (success or failure)
| Field | Type | Required | Description |
|---|---|---|---|
script | string | — | The file location of the script to execute ConstraintsMust be a script file (.sh, .bash, .py, .rb, .js) |
failure_ | string | — | The message to show if the check has failed |
config | block | — | Execution context override for this script |
Configuration
Execution context override for this script
| Field | Type | Required | Description |
|---|---|---|---|
target | referencecontainer, vm | — | Select the sandbox component where this task will run. The task executes commands inside the chosen environment. |
user | string | — | Set the user or group identity under which the task runs inside the container. This helps control permissions. |
group | string | — | Set the user or group identity under which the task runs inside the container. This helps control permissions. |
working_ | string | — | Specify the directory path where the task commands will execute. Leave empty to use the default working directory. |
environment | map(string) | — | Environment variables for script execution |
timeout | string | — | Set how long the task can run before it stops automatically. Use this to prevent tasks from hanging indefinitely. ConstraintsMust be a valid duration (e.g. 30s, 5m) |
success_ | list(number) | — | Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. |
failure_ | list(number) | — | Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. |
parallel_ | block | — | Configure parallel execution for lifecycle scripts |
Parallel Exec
Configure parallel execution for lifecycle scripts
| Field | Type | Required | Description |
|---|---|---|---|
condition | bool | — | Execute all condition blocks in parallel Default false |
check | bool | — | Execute all check scripts in parallel within a condition Default false |
solve | bool | — | Execute all solve scripts in parallel within a condition Default false |
setup | bool | — | Execute all setup scripts in parallel within a condition Default false |
cleanup | bool | — | Execute all cleanup scripts in parallel within a condition Default false |
Default Configuration
Section titled “Default Configuration”The following defaults are applied automatically:
config { timeout = "30s" working_directory = "/" environment = {} user = "root" group = "root" success_exit_codes = [0] failure_exit_codes = []
parallel_exec { condition = false check = false solve = false setup = false cleanup = false }}Examples
Section titled “Examples”Simple File Creation Task
Section titled “Simple File Creation Task”resource "task" "create_file" { description = "Create a configuration file"
config { target = resource.container.ubuntu }
condition "file_exists" { description = "Create /etc/myapp.conf"
check { script = "scripts/task/create_file/check_config_file.sh" }
solve { script = "scripts/task/create_file/create_config_file.sh" } }}Multi-Condition Docker Task
Section titled “Multi-Condition Docker Task”resource "task" "docker_setup" { description = "Set up Docker environment" success_message = "Great! Docker is now configured and running."
config { target = resource.container.ubuntu timeout = "60s" }
condition "install_docker" { description = "Install Docker"
setup { script = "scripts/task/docker_setup/install_docker.sh" }
check { script = "scripts/task/docker_setup/check_docker_installed.sh" failure_message = "Docker installation failed. Check the logs." }
solve { script = "scripts/task/docker_setup/solve_install_docker.sh" } }
condition "start_service" { description = "Start Docker service"
check { script = "scripts/task/docker_setup/check_docker_running.sh" }
solve { script = "scripts/task/docker_setup/start_docker.sh" } }
condition "run_container" { description = "Run a test container"
check { script = "scripts/task/docker_setup/check_test_container.sh"
config { timeout = "45s" } }
solve { script = "scripts/task/docker_setup/run_test_container.sh" }
cleanup { script = "scripts/task/docker_setup/cleanup_test_container.sh" } }}Task with Custom Configuration
Section titled “Task with Custom Configuration”resource "task" "advanced_networking" { description = "Configure advanced network settings"
config { target = resource.container.network_lab user = "student"
environment = { NETWORK_CONFIG = "/etc/networks.conf" DEBUG_MODE = "true" } }
condition "configure_bridge" { description = "Set up bridge network interface"
check { script = "scripts/task/advanced_networking/check_bridge.sh" } }}Parallel Execution Task
Section titled “Parallel Execution Task”resource "task" "parallel_checks" { description = "Run multiple parallel validations"
config { target = resource.container.test_env
parallel_exec { check = true # Run all check scripts in parallel } }
condition "check_service_a" { description = "Validate service A is running"
check { script = "scripts/task/parallel_checks/check_service_a.sh" } }
condition "check_service_b" { description = "Validate service B is running"
check { script = "scripts/task/parallel_checks/check_service_b.sh" } }
condition "check_service_c" { description = "Validate service C is running"
check { script = "scripts/task/parallel_checks/check_service_c.sh" } }}Script Execution Flow
Section titled “Script Execution Flow”Tasks execute scripts in a specific order:
- Setup scripts: Run when a condition becomes active
- Check scripts: Run when validating the condition
- Solve scripts: Run when the user skips the condition
- Cleanup scripts: Run when the condition completes (success or skip)
Within each condition:
- All setup scripts execute first (in order)
- Check scripts execute during validation
- Solve scripts execute only when skipped
- Cleanup scripts execute last (in order)
Usage in Instructions
Section titled “Usage in Instructions”Tasks must be referenced in instruction markdown using the <instruqt-task> component:
## Complete the Setup
<instruqt-task id="docker_setup"></instruqt-task>
Continue to the next step once the task is complete.Best Practices
Section titled “Best Practices”- Clear Descriptions: Write descriptive names for tasks and conditions that explain what users need to do
- Granular Conditions: Break complex tasks into smaller, logical conditions for better user feedback
- Error Messages: Provide helpful failure messages in check scripts
- Timeouts: Set appropriate timeouts based on expected script execution time
- Cleanup: Always clean up resources in cleanup scripts to avoid side effects
- Script Organization: Organize scripts into subdirectories matching the task resource name for easier readability (e.g.,
scripts/task/docker_setup/check_docker.sh). If you need to share a script across multiple tasks, you can customize the directory structure as needed — the convention is a starting point, not a strict requirement. - Configuration Inheritance: Use task-level config for common settings, override at condition/script level when needed
