Skip to content

Lab Environment Functions

Lab environment functions provide access to Instruqt-specific functionality, including Docker configuration, data directories, and system information.

Returns the path to a lab data directory, creating it if necessary.

data(name)

Parameters:

  • name - Name of the data directory

Returns: Absolute path to the data directory

Example:

data("workspace") # Returns: "/root/.jumppad/data/workspace"
data("configs") # Returns: "/root/.jumppad/data/configs"
data("lab-files") # Returns: "/root/.jumppad/data/lab-files"

Returns the path to a lab data directory with specific permissions.

data_with_permissions(name, permissions)

Parameters:

  • name - Name of the data directory
  • permissions - Unix permissions (octal, e.g., 755)

Returns: Absolute path to the data directory

Example:

data_with_permissions("secrets", 700) # Owner read/write/execute only
data_with_permissions("shared", 755) # Owner all, others read/execute
data_with_permissions("public", 777) # Full permissions for all

Returns the Docker host URL for the current environment.

docker_host()

Parameters: None

Returns: Docker host connection string

Example:

docker_host() # Returns: "tcp://docker:2375" or "unix:///var/run/docker.sock"
resource "container" "docker_client" {
environment = {
DOCKER_HOST = docker_host()
}
}

Returns the IP address of the Docker host.

docker_ip()

Parameters: None

Returns: Docker host IP address

Example:

docker_ip() # Returns: "172.17.0.1" (typical Docker bridge IP)
resource "template" "config" {
source = <<-EOF
database:
host: ${docker_ip()}
port: 5432
EOF
destination = "./db-config.yaml"
}

Checks if a file or directory exists.

exists(path)

Parameters:

  • path - Path to check

Returns: Boolean (true if path exists)

Example:

exists("/etc/hosts") # Returns: true
exists("./config.json") # Returns: true/false
exists(data("workspace")) # Returns: true (after creation)

Returns the Jumppad home directory path.

jumppad()

Parameters: None

Returns: Path to Jumppad home directory

Example:

jumppad() # Returns: "/root/.jumppad"
locals {
config_dir = "${jumppad()}/config"
state_file = "${jumppad()}/state.json"
}

Returns system information.

system(property)

Parameters:

  • property - System property to retrieve (“os” or “arch”)

Returns: System property value

Example:

system("os") # Returns: "linux", "darwin", or "windows"
system("arch") # Returns: "amd64", "arm64", etc.
locals {
binary_name = "app-${system("os")}-${system("arch")}"
}

Encodes a string to Base64 (also available in encoding functions).

base64_encode(string)

Parameters:

  • string - String to encode

Returns: Base64-encoded string

Example:

base64_encode("instruqt") # Returns: "aW5zdHJ1cXQ="
base64_encode(var.api_key) # Encode sensitive data

Decodes a Base64 string (also available in encoding functions).

base64_decode(string)

Parameters:

  • string - Base64-encoded string

Returns: Decoded string

Example:

base64_decode("aW5zdHJ1cXQ=") # Returns: "instruqt"
base64_decode(var.encoded_cert) # Decode certificate data
# Create organized workspace structure
locals {
workspace_dir = data("workspace")
config_dir = data("configs")
scripts_dir = data_with_permissions("scripts", 755)
}
resource "copy" "lab_files" {
source = "./files/"
destination = local.workspace_dir
}
resource "template" "setup_script" {
source = <<-EOF
#!/bin/bash
export WORKSPACE="${local.workspace_dir}"
export CONFIG_DIR="${local.config_dir}"
cd $WORKSPACE
EOF
destination = "${local.scripts_dir}/setup.sh"
}
resource "container" "docker_cli" {
image {
name = "docker:cli"
}
environment = {
DOCKER_HOST = docker_host()
}
volume {
source = "/var/run/docker.sock"
destination = "/var/run/docker.sock"
type = "bind"
}
}
resource "template" "docker_config" {
source = jsonencode({
host = docker_ip()
api_version = "1.41"
tls_verify = false
})
destination = "${data("configs")}/docker.json"
}
# Download platform-specific binaries
resource "http" "binary" {
url = "https://example.com/releases/tool-${system("os")}-${system("arch")}.tar.gz"
destination = "${data("downloads")}/tool.tar.gz"
}
# Use platform-specific commands
resource "exec" "install" {
command = system("os") == "darwin" ? "brew" : "apt-get"
arguments = system("os") == "darwin" ?
["install", "tool"] :
["install", "-y", "tool"]
}
# Check for existing configuration
locals {
has_custom_config = exists("./custom-config.json")
config = local.has_custom_config ?
file("./custom-config.json") :
file("./default-config.json")
}
# Create resources based on environment
resource "container" "app" {
count = exists("${data("flags")}/enable-app") ? 1 : 0
image {
name = "app:latest"
}
}
# Create secure directories for sensitive data
locals {
secrets_dir = data_with_permissions("secrets", 700)
certs_dir = data_with_permissions("certificates", 700)
}
resource "template" "api_key" {
source = base64_encode(var.api_key)
destination = "${local.secrets_dir}/api-key.enc"
}
resource "exec" "generate_cert" {
command = "openssl"
arguments = ["req", "-x509", "-newkey", "rsa:4096",
"-keyout", "${local.certs_dir}/key.pem",
"-out", "${local.certs_dir}/cert.pem",
"-days", "365", "-nodes", "-subj", "/CN=localhost"]
}
locals {
state_dir = data("state")
state_file = "${local.state_dir}/lab-state.json"
# Initialize or load state
current_state = exists(local.state_file) ?
jsondecode(file(local.state_file)) :
{ initialized = false }
}
resource "template" "update_state" {
source = jsonencode(merge(local.current_state, {
initialized = true
last_updated = timestamp()
docker_host = docker_host()
platform = system("os")
}))
destination = local.state_file
}
  1. Use Consistent Data Directories: Organize lab files systematically

    locals {
    # Standard directory structure
    dirs = {
    workspace = data("workspace")
    configs = data("configs")
    scripts = data("scripts")
    temp = data("temp")
    }
    }
  2. Set Appropriate Permissions: Use data_with_permissions for security

    locals {
    # Secure sensitive directories
    secrets = data_with_permissions("secrets", 700)
    # Shared readable directories
    public = data_with_permissions("public", 755)
    }
  3. Handle Platform Differences: Use system() for compatibility

    locals {
    # Platform-specific paths
    path_separator = system("os") == "windows" ? "\\" : "/"
    home_dir = system("os") == "windows" ? "C:\\Users\\lab" : "/home/lab"
    }
  4. Check Resource Existence: Always verify before operations

    resource "copy" "optional_files" {
    count = exists("./optional/") ? 1 : 0
    source = "./optional/"
    destination = data("optional")
    }