Encoding Functions
Encoding functions handle conversion between different data formats, including JSON and CSV.
Function Reference
Section titled “Function Reference”csvdecode
Section titled “csvdecode”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"}# ]
jsondecode
Section titled “jsondecode”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('true')# Returns: true
jsonencode
Section titled “jsonencode”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'
Common Use Cases
Section titled “Common Use Cases”Configuration Management
Section titled “Configuration Management”# Parse external configurationlocals { 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 filesresource "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"}
API Integration
Section titled “API Integration”# Prepare data for API requestsresource "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 responselocals { api_response = file("./api-response.json") response_data = jsondecode(local.api_response) user_id = local.response_data.user.id}
CSV Data Processing
Section titled “CSV Data Processing”# Import user data from CSVlocals { users_csv = file("./users.csv") users = csvdecode(local.users_csv)}
# Create resources from CSV dataresource "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 CSVlocals { 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"}
Dynamic Configuration
Section titled “Dynamic Configuration”# Build configuration dynamicallylocals { 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"}
Data Transformation
Section titled “Data Transformation”# Transform CSV to JSONlocals { 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 = tonumber(product.price) category = product.category available = product.in_stock == "true" } ] }}
resource "template" "products" { source = jsonencode(local.products_json) destination = "./products.json"}
Configuration Merging
Section titled “Configuration Merging”# Merge multiple configuration sourceslocals { # Default configuration default_config = jsondecode(file("./config/default.json"))
# Environment-specific configuration env_config_file = "./config/${var.environment}.json" env_config = fileexists(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"}
Metadata Generation
Section titled “Metadata Generation”# Generate metadata for lab resourceslocals { lab_metadata = { lab = { name = var.lab_name version = var.lab_version created_at = var.created_at } resources = { containers = length([for r in local.resources : r if r.type == "container"]) networks = length([for r in local.resources : r if r.type == "network"]) volumes = length([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"}
Secret Management
Section titled “Secret Management”# Handle encrypted configurationlocals { # Read encrypted config (base64 encoded JSON) encrypted_config = var.secret_config decrypted_json = base64decode(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) }}
Best Practices
Section titled “Best Practices”-
Validate JSON Input: Check for parsing errors
locals {# Safely decode with error handlingconfig = try(jsondecode(var.json_input), {error = "Invalid JSON input"})} -
Use Appropriate Data Types: Consider numeric conversions
locals {# Convert string numbers from CSV to actual numbersusers = [for user in csvdecode(file("users.csv")) : {name = user.nameage = tonumber(user.age)active = user.active == "true"}]} -
Handle Missing Files: Check file existence
locals {config = exists("./config.json") ?jsondecode(file("./config.json")) :{default = true}} -
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 toolssource = jsonencode(local.config)destination = "./config.json"}