Skip to content

You are viewing documentation for Instruqt 2.0 Labs. For Tracks documentation, please visit docs.instruqt.com.

Defined intasks.hcl

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.

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.

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"
}
}
}
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"
}
}
}
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[] (optional, repeatable)
├─ 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 override

Fields

FieldTypeRequiredDescription
descriptionstring✓Add a short explanation of what users are expected to achieve
prerequisiteslist(reference)chapter, task, quiz—Tasks that must complete before this task can start
success_messagestring—A message shown to learners when they complete the task correctly. Use it to confirm success or provide a next step.
configblock—Default execution context for all conditions
conditionblock—Validation conditions that must all pass for task completionrepeatable

Configuration

task→Configuration

Default execution context for all conditions

FieldTypeRequiredDescription
targetreferencecontainer, vm, k8s_cluster, kubernetes_cluster, nomad_cluster—Select the sandbox component where this task will run. The task executes commands inside the chosen environment. A cluster runs the script on its server node.
userstring—Set the user or group identity under which the task runs inside the container. This helps control permissions.
groupstring—Set the user or group identity under which the task runs inside the container. This helps control permissions.
working_directorystring—Specify the directory path where the task commands will execute. Leave empty to use the default working directory.
environmentmap(string)—Environment variables for script execution
timeoutstring—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_exit_codeslist(number)—Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. This applies to setup, solve and cleanup scripts as well as checks.
failure_exit_codeslist(number)—Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure.
parallel_execblock—Configure parallel execution for lifecycle scripts

Parallel Exec

task→Configuration→Parallel Exec

Configure parallel execution for lifecycle scripts

FieldTypeRequiredDescription
conditionbool—Execute all condition blocks in parallel
Defaultfalse
checkbool—Execute all check scripts in parallel within a condition
Defaultfalse
solvebool—Execute all solve scripts in parallel within a condition
Defaultfalse
setupbool—Execute all setup scripts in parallel within a condition
Defaultfalse
cleanupbool—Execute all cleanup scripts in parallel within a condition
Defaultfalse

Condition

task→Condition

Validation conditions that must all pass for task completion

FieldTypeRequiredDescription
idlabel✓An internal identifier for the condition. Used to reference this condition within the task configuration. Not visible to learners.
descriptionstring✓Explain what this condition checks or validates for the learner. Keep it short and action-oriented so users understand what success means.
configblock—Use this to override task-level settings for this specific condition. Common overrides include timeout, working directory, or user permissions.
checkblock—Validation scripts to verify task completion (required)repeatable
solveblock—Scripts to automatically solve this conditionrepeatable
setupblock—Scripts to run before checks startrepeatable
cleanupblock—Scripts to run after task completes (success or failure)repeatable

Configuration

task→Condition→Configuration

Execution context override for this condition

FieldTypeRequiredDescription
targetreferencecontainer, vm, k8s_cluster, kubernetes_cluster, nomad_cluster—Select the sandbox component where this task will run. The task executes commands inside the chosen environment. A cluster runs the script on its server node.
userstring—Set the user or group identity under which the task runs inside the container. This helps control permissions.
groupstring—Set the user or group identity under which the task runs inside the container. This helps control permissions.
working_directorystring—Specify the directory path where the task commands will execute. Leave empty to use the default working directory.
environmentmap(string)—Environment variables for script execution
timeoutstring—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_exit_codeslist(number)—Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. This applies to setup, solve and cleanup scripts as well as checks.
failure_exit_codeslist(number)—Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure.
parallel_execblock—Configure parallel execution for lifecycle scripts
Parallel Exec

task→Condition→Configuration→Parallel Exec

Configure parallel execution for lifecycle scripts

FieldTypeRequiredDescription
conditionbool—Execute all condition blocks in parallel
Defaultfalse
checkbool—Execute all check scripts in parallel within a condition
Defaultfalse
solvebool—Execute all solve scripts in parallel within a condition
Defaultfalse
setupbool—Execute all setup scripts in parallel within a condition
Defaultfalse
cleanupbool—Execute all cleanup scripts in parallel within a condition
Defaultfalse

Check

task→Condition→Check

Validation scripts to verify task completion (required)

FieldTypeRequiredDescription
scriptstring—The file location of the script to execute
failure_messagestring—The message to show if the check has failed
configblock—Execution context override for this script
Configuration

task→Condition→Check→Configuration

Execution context override for this script

FieldTypeRequiredDescription
targetreferencecontainer, vm, k8s_cluster, kubernetes_cluster, nomad_cluster—Select the sandbox component where this task will run. The task executes commands inside the chosen environment. A cluster runs the script on its server node.
userstring—Set the user or group identity under which the task runs inside the container. This helps control permissions.
groupstring—Set the user or group identity under which the task runs inside the container. This helps control permissions.
working_directorystring—Specify the directory path where the task commands will execute. Leave empty to use the default working directory.
environmentmap(string)—Environment variables for script execution
timeoutstring—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_exit_codeslist(number)—Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. This applies to setup, solve and cleanup scripts as well as checks.
failure_exit_codeslist(number)—Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure.
parallel_execblock—Configure parallel execution for lifecycle scripts
Parallel Exec

task→Condition→Check→Configuration→Parallel Exec

Configure parallel execution for lifecycle scripts

FieldTypeRequiredDescription
conditionbool—Execute all condition blocks in parallel
Defaultfalse
checkbool—Execute all check scripts in parallel within a condition
Defaultfalse
solvebool—Execute all solve scripts in parallel within a condition
Defaultfalse
setupbool—Execute all setup scripts in parallel within a condition
Defaultfalse
cleanupbool—Execute all cleanup scripts in parallel within a condition
Defaultfalse

Solve

task→Condition→Solve

Scripts to automatically solve this condition

FieldTypeRequiredDescription
scriptstring—The file location of the script to execute
failure_messagestring—The message to show if the check has failed
configblock—Execution context override for this script
Configuration

task→Condition→Solve→Configuration

Execution context override for this script

FieldTypeRequiredDescription
targetreferencecontainer, vm, k8s_cluster, kubernetes_cluster, nomad_cluster—Select the sandbox component where this task will run. The task executes commands inside the chosen environment. A cluster runs the script on its server node.
userstring—Set the user or group identity under which the task runs inside the container. This helps control permissions.
groupstring—Set the user or group identity under which the task runs inside the container. This helps control permissions.
working_directorystring—Specify the directory path where the task commands will execute. Leave empty to use the default working directory.
environmentmap(string)—Environment variables for script execution
timeoutstring—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_exit_codeslist(number)—Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. This applies to setup, solve and cleanup scripts as well as checks.
failure_exit_codeslist(number)—Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure.
parallel_execblock—Configure parallel execution for lifecycle scripts
Parallel Exec

task→Condition→Solve→Configuration→Parallel Exec

Configure parallel execution for lifecycle scripts

FieldTypeRequiredDescription
conditionbool—Execute all condition blocks in parallel
Defaultfalse
checkbool—Execute all check scripts in parallel within a condition
Defaultfalse
solvebool—Execute all solve scripts in parallel within a condition
Defaultfalse
setupbool—Execute all setup scripts in parallel within a condition
Defaultfalse
cleanupbool—Execute all cleanup scripts in parallel within a condition
Defaultfalse

Setup

task→Condition→Setup

Scripts to run before checks start

FieldTypeRequiredDescription
scriptstring—The file location of the script to execute
failure_messagestring—The message to show if the check has failed
configblock—Execution context override for this script
Configuration

task→Condition→Setup→Configuration

Execution context override for this script

FieldTypeRequiredDescription
targetreferencecontainer, vm, k8s_cluster, kubernetes_cluster, nomad_cluster—Select the sandbox component where this task will run. The task executes commands inside the chosen environment. A cluster runs the script on its server node.
userstring—Set the user or group identity under which the task runs inside the container. This helps control permissions.
groupstring—Set the user or group identity under which the task runs inside the container. This helps control permissions.
working_directorystring—Specify the directory path where the task commands will execute. Leave empty to use the default working directory.
environmentmap(string)—Environment variables for script execution
timeoutstring—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_exit_codeslist(number)—Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. This applies to setup, solve and cleanup scripts as well as checks.
failure_exit_codeslist(number)—Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure.
parallel_execblock—Configure parallel execution for lifecycle scripts
Parallel Exec

task→Condition→Setup→Configuration→Parallel Exec

Configure parallel execution for lifecycle scripts

FieldTypeRequiredDescription
conditionbool—Execute all condition blocks in parallel
Defaultfalse
checkbool—Execute all check scripts in parallel within a condition
Defaultfalse
solvebool—Execute all solve scripts in parallel within a condition
Defaultfalse
setupbool—Execute all setup scripts in parallel within a condition
Defaultfalse
cleanupbool—Execute all cleanup scripts in parallel within a condition
Defaultfalse

Cleanup

task→Condition→Cleanup

Scripts to run after task completes (success or failure)

FieldTypeRequiredDescription
scriptstring—The file location of the script to execute
failure_messagestring—The message to show if the check has failed
configblock—Execution context override for this script
Configuration

task→Condition→Cleanup→Configuration

Execution context override for this script

FieldTypeRequiredDescription
targetreferencecontainer, vm, k8s_cluster, kubernetes_cluster, nomad_cluster—Select the sandbox component where this task will run. The task executes commands inside the chosen environment. A cluster runs the script on its server node.
userstring—Set the user or group identity under which the task runs inside the container. This helps control permissions.
groupstring—Set the user or group identity under which the task runs inside the container. This helps control permissions.
working_directorystring—Specify the directory path where the task commands will execute. Leave empty to use the default working directory.
environmentmap(string)—Environment variables for script execution
timeoutstring—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_exit_codeslist(number)—Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure. This applies to setup, solve and cleanup scripts as well as checks.
failure_exit_codeslist(number)—Define success and failure exit codes. Exit code 0 means success, while any other value typically indicates failure.
parallel_execblock—Configure parallel execution for lifecycle scripts
Parallel Exec

task→Condition→Cleanup→Configuration→Parallel Exec

Configure parallel execution for lifecycle scripts

FieldTypeRequiredDescription
conditionbool—Execute all condition blocks in parallel
Defaultfalse
checkbool—Execute all check scripts in parallel within a condition
Defaultfalse
solvebool—Execute all solve scripts in parallel within a condition
Defaultfalse
setupbool—Execute all setup scripts in parallel within a condition
Defaultfalse
cleanupbool—Execute all cleanup scripts in parallel within a condition
Defaultfalse

config.target controls where the task’s scripts (setup, check, solve, cleanup) execute:

  • A container reference (e.g. resource.container.ubuntu) - scripts run inside that container
  • A VM reference (e.g. resource.vm.devbox) - scripts run on that VM through the guest agent
  • No target - scripts run locally on the sandbox host

Task validation works the same on VMs as on containers - point target at the VM and write the check script against the VM’s filesystem and processes.

failure_message is a fixed string in the HCL. A check script cannot set its own message — its output is captured for debugging, not shown to users.

To give different feedback for different causes, write one check block per cause. Every check in a condition runs, and users see the message of each one that failed. A failed check without a failure_message shows a generic message instead.

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
}
}
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"
}
}
}
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"
}
}
}
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"
}
}
}
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"
}
}
}

Tasks execute scripts in a specific order:

  1. Setup scripts: Run when a condition becomes active
  2. Check scripts: Run when validating the condition
  3. Solve scripts: Run when the user skips the condition
  4. 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)

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.
  1. Clear Descriptions: Write descriptive names for tasks and conditions that explain what users need to do
  2. Granular Conditions: Break complex tasks into smaller, logical conditions for better user feedback
  3. Error Messages: Provide helpful failure messages in check scripts
  4. Timeouts: Set appropriate timeouts based on expected script execution time
  5. Cleanup: Always clean up resources in cleanup scripts to avoid side effects
  6. 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.
  7. Configuration Inheritance: Use task-level config for common settings, override at condition/script level when needed