evnx template
Reference documentation for the evnx template command: generate configuration files from templates with variable substitution and filters.
Prerequisites
evnx template — Command Reference
Generate configuration files from templates using .env variables, with support for flexible substitution syntax and powerful filter transformations.
Before you start
When to use this command: Use evnx template when you need to generate environment-specific configuration files (YAML, JSON, TOML, etc.) from a template, injecting values from your .env file. Ideal for CI/CD pipelines, Docker builds, or multi-environment deployments.
Command signature
evnx template --input <TEMPLATE> --output <OUTPUT> [--env <ENV_FILE>] [--verbose]Required arguments
| Argument | Type | Description |
|---|---|---|
--input, -i | path | Path to the template file (e.g., config.yaml.template) |
--output, -o | path | Path where the generated configuration file will be written |
Optional options
| Flag | Type | Default | Description |
|---|---|---|---|
--env, -e | path | .env | Path to the environment file containing variable definitions |
--gitignore | bool | false | Automatically add the output file to .gitignore. No prompt. Mutually exclusive with --no-gitignore |
--no-gitignore | bool | false | Skip all .gitignore checks and warnings. Mutually exclusive with --gitignore |
--verbose, -v | bool | false | Enable detailed progress output to stderr |
--help, -h | bool | false | Display help information |
Gitignore protection
Generated config files contain real values injected from .env and must never be committed. After writing the output file, evnx template can automatically add it to .gitignore.
Behaviour by flag and context
| Context | --gitignore | --no-gitignore | No flag |
|---|---|---|---|
| Interactive terminal | Auto-write, no prompt | Skip, no warning | Prompt: Add config.toml to .gitignore? [Y/n] |
| CI / non-interactive | Auto-write, no prompt | Skip, no warning | Warn only — does not prompt, does not write |
Already in .gitignore | Print "already in .gitignore" | Skip silently | Skip silently |
| No git repository found | Warn "not a git repository" | Skip silently | Skip silently |
The default (--no-gitignore absent) is safe in both contexts: interactive users get a one-keystroke prompt, CI pipelines get a visible warning without a blocking prompt.
What gets written
Entries are grouped under a labelled section so they are easy to identify:
# ── evnx generated ─────────────────────────────────────────
# Files generated by `evnx template` may contain secrets — do not commit.
config.toml
k8s/configmap.yamlRunning evnx template again with the same --output detects the existing entry and prints "already in .gitignore" without adding a duplicate.
Git root detection
evnx walks ancestor directories from the current working directory looking for a .git entry (directory or file, so worktrees are supported). The .gitignore is located at that root. If no .git ancestor is found, the check is skipped with a warning when --gitignore is explicitly set.
The entry written to .gitignore is always relative to the git root, regardless of where you run the command from.
Output files outside the repository root cannot be protected. If --output points to a path outside the directory containing .git/, evnx warns and skips the .gitignore update — gitignore patterns cannot cover paths outside the repository.
Variable substitution syntax
The template engine supports three styles for referencing variables from your .env file:
| Syntax | Example | Description |
|---|---|---|
\${VAR} | \${DATABASE_URL} | Shell-style (bash-like); most portable |
{{VAR}} | {{DATABASE_URL}} | Template-style (Jinja-like); recommended for filters |
$VAR | $DATABASE_URL | Simple prefix style; use with word boundaries |
Pattern precedence: Filters are processed before simple substitution. This ensures is not accidentally replaced by a plain pattern.
Filter transformations
Apply transformations to variable values using the pipe (|) operator within double braces:
{{VAR|filter}}Supported filters
| Filter | Description | Example |
|---|---|---|
|upper | Convert to uppercase | Input: production → Output: PRODUCTION |
|lower | Convert to lowercase | Input: PRODUCTION → Output: production |
|title | Capitalize first letter | Input: hello world → Output: Hello world |
|bool | Convert to boolean string | Input: yes or 1 → Output: true; others → false |
|int | Parse as 64-bit integer | Input: 8000 → Output: 8000; errors on invalid input |
|json | JSON-escape for safe embedding | See example below |
|default:value | Fallback if variable is empty or undefined | Input: "" → Output: value; Input: actual → Output: actual |
Filters are not chainable. Each filter is applied independently — and cannot be combined on the same variable reference. Use separate template variables or validate values in your .env file before templating.
JSON filter example
The |json filter properly escapes values for embedding in JSON structures:
# If VALUE = hello "world"
# Template: "desc": {{VALUE|json}}
# Output: "desc": "hello \"world\""Integer filter errors: The filter will fail if the value cannot be parsed as an integer. This prevents silent configuration errors. Use the filter on a separate variable reference as a fallback if the variable might be missing.
Basic usage examples
Generate a config file from template
# Simple substitution: replace ${VAR} patterns with .env values
evnx template --input config.yaml.template --output config.yamlUse a custom environment file
# Generate production config using .env.production
evnx template -i deploy.yaml.tpl -o deploy.yaml --env .env.productionEnable verbose output for debugging
# See detailed progress and variable loading info
evnx template -i template.json -o output.json --verboseGenerate multiple configs in a script
#!/bin/bash
# Generate configs for multiple environments — auto-protect output files in CI
for env in dev staging prod; do
evnx template \
--input config.yaml.template \
--output "config.${env}.yaml" \
--env ".env.${env}" \
--gitignore \
--verbose
doneOpt out of gitignore management
# You manage .gitignore externally (e.g. via a generator or monorepo tooling)
evnx template \
--input config.yaml.template \
--output config.yaml \
--env .env.production \
--no-gitignoreWhen to use evnx template
| Scenario | Why use this command |
|---|---|
| CI/CD pipeline config generation | Generate environment-specific configs at build time without committing secrets |
| Docker/Kubernetes deployments | Create docker-compose.yml or k8s/ manifests from templates using runtime env vars |
| Multi-environment setups | Maintain one template file, generate config.dev.yaml, config.prod.yaml, etc. |
| Dynamic configuration injection | Inject values from .env into config formats that don't natively support env vars (JSON, TOML) |
| Safe secret handling | Use |json filter to properly escape values; avoid manual string concatenation bugs |
Pro tip: Store your template files with a .template or .tpl extension and commit them to version control. Generated output files contain real secrets — use --gitignore to let evnx add them to .gitignore automatically, or add them manually. Never commit generated output.
Exit codes
| Code | Meaning | Use case |
|---|---|---|
0 | ✅ Template processed successfully | Success in scripts/CI |
1 | 🚨 Processing failed | Missing files, parse errors, or invalid filter values (e.g. non-integer for |int) |
2+ | ⚠️ Runtime error | I/O failures, file permission issues, or unexpected OS-level errors |
Troubleshooting
"Failed to parse environment file" error
✗ Failed to parse environment file: .env.production
Solution: Validate your .env file syntax or run evnx validate --env .env.production to check for issues. Ensure the file uses valid KEY=VALUE syntax:
- ›One variable per line
- ›No spaces around
=(KEY=value, notKEY = value) - ›Quote values with spaces:
KEY="value with spaces" - ›Use
#for comments
"Variable 'X' referenced but not defined" warning
⚠️ Variable 'MISSING_VAR' referenced in template but not defined in .env
ℹ️ Tip: Define 1 undefined variable to avoid runtime issues
Solution: Add the missing variable to your .env file, or use the |default:value filter to provide a fallback:
{{MISSING_VAR|default:fallback_value}}Filter transformation errors
✗ Failed to process template substitutions
Caused by: Variable 'PORT' value 'not-a-number' is not a valid integer for |int filter
Solution: Ensure the variable value in your .env file is a valid integer. If the variable might be absent or malformed, provide a validated default in .env rather than relying on the template:
# In .env — validate and set a safe default before templating
PORT=${PORT:-8000}Or use the |default filter on a separate variable:
# Only use |default — filters cannot be chained
{{PORT|default:8000}}"Not a git repository" warning with --gitignore
⚠️ Not a git repository — cannot update .gitignore
Cause: evnx walks ancestor directories looking for .git/ and reached the filesystem root without finding one. This happens when running outside a git repository or from a temp directory in CI.
Solutions:
- ›Run the command from within your repository root
- ›If you are not using git, add
--no-gitignoreto silence the warning - ›If using git worktrees, the
.gitfile (not directory) is also detected correctly
Output file already in .gitignore
✓ 'config.toml' is already in .gitignore
This is correct behavior — idempotent. evnx checks for an exact line match before writing. Running evnx template multiple times with the same --output and --gitignore will never produce duplicate entries.
JSON filter output has unexpected quotes
# Template: key={{VALUE|json}}
# Output: key="hello \"world\""This is correct behavior. The |json filter returns a properly quoted JSON string literal, including the surrounding double quotes. Use it when embedding values directly inside JSON structures:
{
"description": {{DESCRIPTION|json}}
}If DESCRIPTION = hello "world", the output will be:
{
"description": "hello \"world\""
}Environment variables
| Variable | Values | Default | Description |
|---|---|---|---|
NO_COLOR | 1, true | false | Disable colored output for terminals or log files |
CI | 1, true | false | Auto-enable non-interactive mode (affects verbose output formatting) |
See also
- ›Template Syntax Guide — Deep dive into substitution patterns and filter reference
- ›Gitignore Protection — How evnx detects git roots, writes entries, and handles edge cases
- ›Configuration Management — Strategies for managing configs across environments
- ›CI/CD Integration — Automating config generation in pipelines
- ›Security Best Practices — Safely handling sensitive values in templates
- ›evnx sync — Keep
.envand.env.examplesynchronized before templating