Skip to content

You are viewing documentation for Instruqt 2.0 Labs - our upcoming product releasing in September 2026. For current Tracks documentation, please visitdocs.instruqt.com.

Template


Defined insandbox.hcl

The template resource processes Handlebars templates and outputs the result as a file. It enables dynamic configuration file generation using variable substitution and helper functions.

As a lab author, you can use template resources to:

  • Configuration File Generation: Create dynamic configuration files for web servers (e.g. Nginx, Apache), databases, and applications
  • Infrastructure as Code: Generate Terraform configurations, Kubernetes manifests, and Docker Compose files with environment-specific values

Template resources enable flexible, maintainable configuration management across different environments and deployment scenarios.

resource "template" "name" {
source = "config.tpl"
destination = "./config/app.conf"
variables = {
port = "8080"
host = "localhost"
}
}
resource "template" "name" {
source = <<-EOF
server {
listen {{port}};
server_name {{host}};
root {{document_root}};
location / {
proxy_pass http://{{backend_host}}:{{backend_port}};
}
}
EOF
destination = "./nginx/sites-available/app.conf"
variables = {
port = "80"
host = "app.example.com"
document_root = "/var/www/html"
backend_host = "127.0.0.1"
backend_port = "3000"
}
}

Fields

FieldTypeRequiredDescription
sourcestringPath to a template file or an inline Handlebars template string. File paths are relative to the HCL file.
destinationstringPath where the processed template will be written. Must be an absolute path.
variablesmap(string)Key-value pairs that will be available as template variables in the Handlebars template

Computed Attributes

These attributes are set by the system and are read-only.

AttributeTypeDescription
checksumstringChecksum of the processed template

Templates use Handlebars syntax (based on Mustache):

server_name = "{{hostname}}"
port = {{port}}
debug = {{#if debug}}true{{else}}false{{/if}}
HelperDescriptionExample
quoteWraps string in quotes{{quote database_name}}“mydb”
trimRemoves whitespace{{trim “ hello “}}“hello”
resource "template" "nginx_config" {
source = <<-EOF
upstream backend {
server {{backend_server}};
}
server {
listen {{port}};
location / {
proxy_pass http://backend;
}
}
EOF
destination = "./nginx.conf"
variables = {
backend_server = "127.0.0.1:3000"
port = "80"
}
}
resource "template" "app_config" {
source = "./templates/app.conf.tpl"
destination = "./config/app.conf"
variables = {
database_url = "postgres://localhost/myapp"
redis_url = "redis://localhost:6379"
}
}
resource "template" "nginx_site" {
source = <<-EOF
server {
listen {{port}};
server_name {{server_name}};
root {{document_root}};
location / {
try_files $uri $uri/ =404;
}
location /reference/ {
proxy_pass http://{{api_host}}:{{api_port}};
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
EOF
destination = "./nginx/sites-available/webapp"
variables = {
port = "80"
server_name = "webapp.local"
document_root = "/var/www/webapp"
api_host = "localhost"
api_port = "3000"
}
}
resource "template" "app_config" {
source = "./templates/application.yml.tpl"
destination = "./config/application.yml"
variables = {
database_host = "db.example.com"
database_port = "5432"
database_name = "production_db"
redis_host = "cache.example.com"
redis_port = "6379"
log_level = "info"
external_api_url = "https://api.external.com"
}
}
resource "template" "docker_compose" {
source = <<-EOF
version: '3.8'
services:
web:
image: nginx:{{nginx_version}}
ports:
- "{{web_port}}:80"
volumes:
- ./html:/usr/share/nginx/html
environment:
- NGINX_HOST={{host}}
api:
image: node:{{node_version}}
ports:
- "{{api_port}}:3000"
environment:
- DATABASE_URL={{quote database_url}}
- REDIS_URL={{quote redis_url}}
depends_on:
- db
- redis
db:
image: postgres:{{postgres_version}}
environment:
- POSTGRES_DB={{database_name}}
- POSTGRES_USER={{database_user}}
- POSTGRES_PASSWORD={{quote database_password}}
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:{{redis_version}}
volumes:
postgres_data:
EOF
destination = "./docker-compose.yml"
variables = {
nginx_version = "1.21"
node_version = "16-alpine"
postgres_version = "13"
redis_version = "6-alpine"
web_port = "8080"
api_port = "3000"
host = "localhost"
database_url = "postgres://user:pass@db:5432/myapp"
redis_url = "redis://redis:6379"
database_name = "myapp"
database_user = "app_user"
database_password = "secure_password"
}
}
resource "template" "k8s_deployment" {
source = <<-EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{app_name}}
namespace: {{namespace}}
spec:
replicas: {{replicas}}
selector:
matchLabels:
app: {{app_name}}
template:
metadata:
labels:
app: {{app_name}}
spec:
containers:
- name: {{app_name}}
image: {{image}}:{{tag}}
ports:
- containerPort: {{container_port}}
env:
- name: DATABASE_URL
value: {{quote database_url}}
- name: LOG_LEVEL
value: {{quote log_level}}
resources:
requests:
memory: {{quote memory_request}}
cpu: {{quote cpu_request}}
limits:
memory: {{quote memory_limit}}
cpu: {{quote cpu_limit}}
EOF
destination = "./k8s/deployment.yaml"
variables = {
app_name = "my-web-app"
namespace = "production"
replicas = "3"
image = "my-app"
tag = "v1.2.0"
container_port = "3000"
database_url = "postgres://db:5432/app"
log_level = "info"
memory_request = "256Mi"
cpu_request = "250m"
memory_limit = "512Mi"
cpu_limit = "500m"
}
}
resource "template" "app_settings" {
source = <<-EOF
[server]
host = {{quote host}}
port = {{port}}
{{#if ssl_enabled}}
ssl_cert = {{quote ssl_cert_path}}
ssl_key = {{quote ssl_key_path}}
{{/if}}
[database]
url = {{quote database_url}}
pool_size = {{db_pool_size}}
[logging]
level = {{quote log_level}}
{{#if debug_mode}}
debug = true
verbose = true
{{else}}
debug = false
verbose = false
{{/if}}
[features]
{{#each features}}
{{@key}} = {{this}}
{{/each}}
EOF
destination = "./config/app.toml"
variables = {
host = "0.0.0.0"
port = "8080"
ssl_enabled = "true"
ssl_cert_path = "/certs/server.crt"
ssl_key_path = "/certs/server.key"
database_url = "postgres://localhost/app"
db_pool_size = "10"
log_level = "info"
debug_mode = "false"
features = {
auth_enabled = "true"
metrics_enabled = "true"
cache_enabled = "false"
}
}
}

Templates are commonly used to generate configuration files for containers:

resource "template" "redis_config" {
source = <<-EOF
port {{port}}
bind {{bind_address}}
save {{save_interval}} {{save_changes}}
appendonly {{appendonly}}
appendfsync {{appendfsync}}
{{#if password}}
requirepass {{password}}
{{/if}}
EOF
destination = "./redis/redis.conf"
variables = {
port = "6379"
bind_address = "127.0.0.1"
save_interval = "900"
save_changes = "1"
appendonly = "yes"
appendfsync = "everysec"
password = "redis_password"
}
}
resource "container" "redis" {
image {
name = "redis:6-alpine"
}
volume {
source = resource.template.redis_config.destination
destination = "/usr/local/etc/redis/redis.conf"
type = "bind"
}
command = ["redis-server", "/usr/local/etc/redis/redis.conf"]
}
  1. File Organization: Store templates in a dedicated templates/ directory
  2. Variable Naming: Use clear, descriptive variable names
  3. Default Values: Consider providing default values in templates using conditionals
  4. Validation: Test templates with different variable values
  5. Security: Be cautious with sensitive data in variables - consider using external sources
  6. Documentation: Comment complex template logic for maintainability
  7. Path Management: Use absolute paths or paths relative to config files