Skip to content

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

Encoding Functions


Encoding functions handle conversion between different data formats, including JSON and CSV.

Decodes CSV-formatted data into a list of maps.

csvdecode(string)

Parameters:

  • string - CSV-formatted string

Returns: List of maps representing rows

Example:

csvdecode("name,age\nAlice,30\nBob,25")
# Returns: [
# {name = "Alice", age = "30"},
# {name = "Bob", age = "25"}
# ]
csvdecode("host,port\nweb,80\napi,8080")
# Returns: [
# {host = "web", port = "80"},
# {host = "api", port = "8080"}
# ]

Parses a JSON string into HCL values.

jsondecode(string)

Parameters:

  • string - JSON-formatted string

Returns: Decoded HCL value (map, list, string, number, bool)

Example:

jsondecode('{"name": "lab", "port": 8080}')
# Returns: {name = "lab", port = 8080}
jsondecode('["a", "b", "c"]')
# Returns: ["a", "b", "c"]
jsondecode('"hello"')
# Returns: "hello"
jsondecode('42')
# Returns: 42
jsondecode('19.99')
# Returns: 19.99
jsondecode('true')
# Returns: true

Converts HCL values to JSON format.

jsonencode(value)

Parameters:

  • value - Any HCL value to encode

Returns: JSON-formatted string

Example:

jsonencode({name = "lab", port = 8080})
# Returns: '{"name":"lab","port":8080}'
jsonencode(["a", "b", "c"])
# Returns: '["a","b","c"]'
jsonencode("hello")
# Returns: '"hello"'
jsonencode(42)
# Returns: '42'
jsonencode(true)
# Returns: 'true'
# Parse external configuration
locals {
config_json = file("./config.json")
config = jsondecode(local.config_json)
# Access nested values
api_url = local.config.api.url
timeout = local.config.settings.timeout
}
# Generate configuration files
resource "template" "app_config" {
source = jsonencode({
database = {
host = var.db_host
port = var.db_port
name = var.db_name
}
features = var.enabled_features
debug = var.debug_mode
})
destination = "./app-config.json"
}
# Prepare data for API requests
resource "http" "webhook" {
url = "https://api.example.com/webhook"
method = "POST"
body = jsonencode({
event = "lab_started"
user_id = var.user_id
metadata = {
lab_name = var.lab_name
started_at = var.start_time
}
})
headers = {
"Content-Type" = "application/json"
}
}
# Parse API response
locals {
api_response = file("./api-response.json")
response_data = jsondecode(local.api_response)
user_id = local.response_data.user.id
}
# Import user data from CSV
locals {
users_csv = file("./users.csv")
users = csvdecode(local.users_csv)
}
# Create resources from CSV data
resource "container" "user_workspace" {
for_each = {
for user in local.users : user.username => user
}
image {
name = "workspace:latest"
}
environment = {
USERNAME = each.value.username
EMAIL = each.value.email
ROLE = each.value.role
USER_ID = each.value.id
}
}
# Process server inventory from CSV
locals {
servers_csv = csvdecode(file("./servers.csv"))
# CSV format: hostname,ip,role,region
}
resource "template" "inventory" {
source = jsonencode({
servers = [
for server in local.servers_csv : {
hostname = server.hostname
ip = server.ip
role = server.role
region = server.region
}
]
})
destination = "./inventory.json"
}
# Build configuration dynamically
locals {
base_config = {
app_name = var.app_name
version = var.app_version
}
environment_config = var.environment == "production" ? {
log_level = "warn"
debug = false
replicas = 3
} : {
log_level = "debug"
debug = true
replicas = 1
}
final_config = merge(local.base_config, local.environment_config)
}
resource "template" "config" {
source = jsonencode(local.final_config)
destination = "./runtime-config.json"
}
# Transform CSV to JSON
locals {
products_csv = csvdecode(file("./products.csv"))
# CSV columns: name,price,category,in_stock
products_json = {
products = [
for product in local.products_csv : {
name = product.name
price = jsondecode(product.price) # "19.99" -> 19.99
category = product.category
available = product.in_stock == "true"
}
]
}
}
resource "template" "products" {
source = jsonencode(local.products_json)
destination = "./products.json"
}
# Merge multiple configuration sources
locals {
# Default configuration
default_config = jsondecode(file("./config/default.json"))
# Environment-specific configuration
env_config_file = "./config/${var.environment}.json"
env_config = exists(env_config_file) ?
jsondecode(file(env_config_file)) : {}
# User overrides
user_overrides = var.config_overrides != "" ?
jsondecode(var.config_overrides) : {}
# Final merged configuration
merged_config = merge(
local.default_config,
local.env_config,
local.user_overrides
)
}
resource "template" "final_config" {
source = jsonencode(local.merged_config)
destination = "./app-config.json"
}
# Generate metadata for lab resources
locals {
lab_metadata = {
lab = {
name = var.lab_name
version = var.lab_version
created_at = var.created_at
}
resources = {
containers = len([for r in local.resources : r if r.type == "container"])
networks = len([for r in local.resources : r if r.type == "network"])
volumes = len([for r in local.resources : r if r.type == "volume"])
}
configuration = {
debug_mode = var.debug_enabled
log_level = var.log_level
feature_flags = var.feature_flags
}
}
}
resource "template" "metadata" {
source = jsonencode(local.lab_metadata)
destination = "./lab-metadata.json"
}
# Handle encrypted configuration
locals {
# Read encrypted config (base64 encoded JSON)
encrypted_config = var.secret_config
decrypted_json = base64_decode(local.encrypted_config)
secret_config = jsondecode(local.decrypted_json)
}
resource "container" "app" {
environment = {
DATABASE_URL = local.secret_config.database.url
API_KEY = local.secret_config.api.key
# Store the full config as JSON
CONFIG_JSON = jsonencode(local.secret_config)
}
}
  1. Validate JSON Input: Check for parsing errors

    locals {
    # Safely decode with error handling
    config = var.json_input != "" ? jsondecode(var.json_input) : {}
    }
  2. Use Appropriate Data Types: Consider numeric conversions

    locals {
    # Convert string numbers from CSV to actual numbers
    users = [
    for user in csvdecode(file("users.csv")) : {
    name = user.name
    age = parseint(user.age, 10)
    active = user.active == "true"
    }
    ]
    }
  3. Handle Missing Files: Check file existence

    locals {
    config = exists("./config.json") ?
    jsondecode(file("./config.json")) :
    {default = true}
    }
  4. Format JSON Output: Use proper indentation for readability

    resource "template" "readable_config" {
    # Note: jsonencode produces compact JSON
    # For pretty-printed JSON, you may need external tools
    source = jsonencode(local.config)
    destination = "./config.json"
    }