Skip to content

Filesystem Functions

Filesystem functions provide operations for reading files and accessing environment information.

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 PATH
env("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 contents
file("../data.txt") # Returns file contents from parent directory
file("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"

Renders a template file with variables using Handlebars syntax.

template_file(path, vars)

Parameters:

  • path - Path to template file
  • vars - 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}};
# }
# Read and parse configuration
locals {
config_content = file("./config.json")
config = jsondecode(local.config_content)
}
# Check if we're in development
locals {
is_dev = env("NODE_ENV") == "development"
}
# Generate configuration from template
resource "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"
}
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"
}
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"
}
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)
}
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()
}
}
# Complex template with conditionals and loops
resource "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}}
# }
  1. Use Relative Paths: Paths in file() are relative to the current HCL file

    # Good - relative to current file
    config = file("./config.json")
    # Avoid absolute paths unless necessary
  2. Handle Missing Files: file() will error if file doesn’t exist

    # Use exists() from lab environment functions to check first
    config = exists("./config.json") ?
    file("./config.json") :
    "{\"default\": true}"
  3. Environment Variable Defaults: Always provide fallbacks

    locals {
    port = env("PORT") != "" ? env("PORT") : "8080"
    debug = env("DEBUG") == "true"
    }
  4. Template Organization: Keep templates in a dedicated directory

    # Organize templates consistently
    nginx_config = template_file("./templates/nginx.conf.tpl", {})
    app_config = template_file("./templates/app.conf.tpl", {})