Filesystem Functions
Filesystem functions provide operations for reading files and accessing environment information.
Function Reference
Section titled “Function Reference”Returns the directory portion of a file path.
dir()
Parameters: None
Returns: Directory path of the current HCL file
Example:
dir() # Returns: "/workspace/lab" (directory of current .hcl file)
Gets the value of an environment variable.
env(name)
Parameters:
name
- Environment variable name
Returns: Environment variable value or empty string
Example:
env("HOME") # Returns: "/home/user"env("PATH") # Returns: system PATHenv("CUSTOM_VAR") # Returns: value or ""
Reads the contents of a file.
file(path)
Parameters:
path
- Path to file (relative to current HCL file)
Returns: File contents as string
Example:
file("./config.json") # Returns file contentsfile("../data.txt") # Returns file contents from parent directoryfile("config/settings.yaml") # Returns file contents from subdirectory
Returns the user’s home directory.
home()
Parameters: None
Returns: User home directory path
Example:
home() # Returns: "/home/user" or "/Users/user"
template_file
Section titled “template_file”Renders a template file with variables using Handlebars syntax.
template_file(path, vars)
Parameters:
path
- Path to template filevars
- Map of template variables
Returns: Rendered template string
Template Syntax: Uses Handlebars templating with additional helpers:
{{quote "string"}}
- Wraps string in quotes{{trim "string"}}
- Trims whitespace
Example:
template_file("./nginx.conf.tpl", { server_name = var.domain port = var.port root = var.document_root})
# Template file content (nginx.conf.tpl):# server {# listen {{port}};# server_name {{quote server_name}};# root {{trim root}};# }
Common Use Cases
Section titled “Common Use Cases”Configuration File Management
Section titled “Configuration File Management”# Read and parse configurationlocals { config_content = file("./config.json") config = jsondecode(local.config_content)}
# Check if we're in developmentlocals { is_dev = env("NODE_ENV") == "development"}
Template Processing
Section titled “Template Processing”# Generate configuration from templateresource "template" "app_config" { source = template_file("./templates/app.conf.tpl", { environment = var.environment database_url = var.db_connection_string api_keys = var.api_keys debug_mode = env("DEBUG") == "true" })
destination = "./app.conf"}
Path Construction
Section titled “Path Construction”locals { # Build paths relative to current file current_dir = dir() config_file = "${local.current_dir}/config.json"
# Use home directory user_config = "${home()}/.config/app/settings.json"}
Environment-based Configuration
Section titled “Environment-based Configuration”locals { # Use environment variables with defaults log_level = env("LOG_LEVEL") != "" ? env("LOG_LEVEL") : "info" debug_enabled = env("DEBUG") == "true"
# Build configuration based on environment config = { log_level = local.log_level debug = local.debug_enabled home_dir = home() }}
resource "template" "env_config" { source = template_file("./config.tpl", local.config) destination = "./runtime-config.json"}
Multi-file Configuration
Section titled “Multi-file Configuration”locals { # Read multiple configuration files base_config = jsondecode(file("./config/base.json")) env_config = jsondecode(file("./config/${env("ENVIRONMENT")}.json"))
# Merge configurations final_config = merge(local.base_config, local.env_config)}
Secret Management
Section titled “Secret Management”locals { # Read secrets from files (ensure proper permissions) api_key_file = "${home()}/.secrets/api-key" api_key = file(local.api_key_file)}
resource "container" "app" { environment = { API_KEY = trimspace(local.api_key) HOME_DIR = home() CONFIG_DIR = dir() }}
Template with Complex Logic
Section titled “Template with Complex Logic”# Complex template with conditionals and loopsresource "template" "nginx_config" { source = template_file("./nginx.conf.tpl", { server_name = var.domain ssl_enabled = var.enable_ssl upstream_servers = var.backend_servers worker_processes = env("WORKER_PROCESSES") != "" ? env("WORKER_PROCESSES") : "auto" })
destination = "./nginx.conf"}
# Template file (nginx.conf.tpl):# worker_processes {{worker_processes}};## server {# listen {{#if ssl_enabled}}443 ssl{{else}}80{{/if}};# server_name {{quote server_name}};## {{#each upstream_servers}}# upstream backend_{{@index}} {# server {{this}};# }# {{/each}}# }
Best Practices
Section titled “Best Practices”-
Use Relative Paths: Paths in file() are relative to the current HCL file
# Good - relative to current fileconfig = file("./config.json")# Avoid absolute paths unless necessary -
Handle Missing Files: file() will error if file doesn’t exist
# Use exists() from lab environment functions to check firstconfig = exists("./config.json") ?file("./config.json") :"{\"default\": true}" -
Environment Variable Defaults: Always provide fallbacks
locals {port = env("PORT") != "" ? env("PORT") : "8080"debug = env("DEBUG") == "true"} -
Template Organization: Keep templates in a dedicated directory
# Organize templates consistentlynginx_config = template_file("./templates/nginx.conf.tpl", {})app_config = template_file("./templates/app.conf.tpl", {})