Template Syntax
Complete guide to Go template syntax used in Conjure.
Conjure uses Go's template engine, which provides powerful text transformation capabilities. This guide covers all the syntax you need to create dynamic templates.
Replace placeholders with variable values:
name: {{.app_name}}
namespace: {{.namespace}}
port: {{.port}}
Input variables:
app_name: my-api
namespace: production
port: 8080
The . (dot) refers to the current context, which is your variables object:
{{.variable_name}}
{{if .enable_monitoring}}
monitoring:
enabled: true
{{end}}
When enable_monitoring: true:
monitoring:
enabled: true
When enable_monitoring: false:
# Nothing rendered
{{if .enable_tls}}
protocol: https
port: 443
{{else}}
protocol: http
port: 80
{{end}}
{{if eq .environment "production"}}
replicas: 10
{{else if eq .environment "staging"}}
replicas: 5
{{else}}
replicas: 1
{{end}}
{{if not .enable_debug}}
logLevel: info
{{else}}
logLevel: debug
{{end}}
{{if eq .service_type "LoadBalancer"}}
externalTrafficPolicy: Local
{{end}}
Multiple values:
{{if eq .environment "production" "prod" "prd"}}
# Matches if environment is any of these values
{{end}}
{{if ne .environment "development"}}
# Renders if environment is NOT development
{{end}}
| Operator | Meaning | Example |
|---|---|---|
eq | Equal | {{if eq .env "prod"}} |
ne | Not equal | {{if ne .env "dev"}} |
Important
Numeric Comparisons Not Supported: While Go templates support numeric comparison operators (
lt,le,gt,ge), Conjure stores all variables as strings regardless of thetypefield in metadata. This means numeric comparisons will not work as expected. Use string comparisons witheqandneinstead.For example, instead of
{{if ge .replicas 5}}, use categorical variables likescale_tierwith valuessmall,medium,largeand compare with{{if eq .scale_tier "large"}}.
{{if and .enable_tls .enable_auth}}
# Renders if both are true
secureMode: true
{{end}}
{{if or .is_production .is_staging}}
# Renders if either is true
highAvailability: true
{{end}}
{{if and (eq .environment "production") (eq .scale_tier "large")}}
# Production AND large scale
autoscaling: true
{{end}}
Templates preserve whitespace:
{{if .feature}}
enabled: true
{{end}}
Output with feature: true:
enabled: true
Notice the blank lines.
Use - to trim whitespace:
{{- if .feature}}
enabled: true
{{- end}}
Output:
enabled: true
Left trim:
{{- .value}}
Right trim:
{{.value -}}
Both:
{{- .value -}}
apiVersion: v1
kind: Service
metadata:
name: {{.app_name}}
{{- if .enable_monitoring}}
annotations:
prometheus.io/scrape: "true"
{{- end}}
spec:
selector:
app: {{.app_name}}
Without -, you'd get blank lines in the output.
Comments that don't appear in output:
{{/* This is a comment */}}
apiVersion: v1
kind: Service
Multi-line comments:
{{/*
This is a multi-line comment
It won't appear in the output
*/}}
Regular YAML comments appear in output:
# This is a YAML comment - appears in output
apiVersion: v1
message: {{print "Hello " .name "!"}}
Output with name: World:
message: Hello World!
version: {{printf "v%s" .version}}
Output with version: 1.2.3:
version: v1.2.3
{{if .enable_database}}
database:
{{if eq .database_type "postgres"}}
type: postgresql
port: 5432
{{else if eq .database_type "mysql"}}
type: mysql
port: 3306
{{else}}
type: sqlite
{{end}}
{{end}}
{{if and (eq .environment "production") (eq .region "us-east-1")}}
# Specific production region config
{{else if eq .environment "production"}}
# General production config
{{else}}
# Other environments
{{end}}
metadata:
labels:
app: {{.app_name}}
environment: {{.environment}}
{{- if .team}}
team: {{.team}}
{{- end}}
{{- if .cost_center}}
cost-center: {{.cost_center}}
{{- end}}
{{if eq .environment "production"}}
replicas: 10
resources:
requests:
cpu: 1000m
memory: 2Gi
limits:
cpu: 2000m
memory: 4Gi
{{else if eq .environment "staging"}}
replicas: 3
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1000m
memory: 2Gi
{{else}}
replicas: 1
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 500m
memory: 1Gi
{{end}}
spec:
containers:
- name: {{.app_name}}
image: {{.image}}
{{- if .enable_health_checks}}
livenessProbe:
httpGet:
path: /health
port: {{.port}}
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: {{.port}}
initialDelaySeconds: 5
periodSeconds: 5
{{- end}}
{{- if .enable_metrics}}
env:
- name: METRICS_ENABLED
value: "true"
- name: METRICS_PORT
value: "{{.metrics_port}}"
{{- end}}
spec:
type: {{.service_type}}
{{- if eq .service_type "LoadBalancer"}}
loadBalancerSourceRanges:
- {{.allowed_cidr}}
externalTrafficPolicy: Local
{{- else if eq .service_type "NodePort"}}
sessionAffinity: ClientIP
{{- end}}
Add temporary debug output:
{{/* DEBUG: app_name = {{.app_name}} */}}
{{/* DEBUG: replicas = {{.replicas}} */}}
Generate and check the comments in output.
If your template has syntax errors, you'll see:
Error: failed to parse template
Common issues:
- Unclosed
{{if}}(missing{{end}}) - Typo in function name
- Missing closing braces
}}
# Good - clean output
{{- if .feature}}
enabled: true
{{- end}}
# Bad - extra blank lines
{{if .feature}}
enabled: true
{{end}}
# Good - clear structure
{{- if .enable_monitoring}}
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
{{- end}}
# Bad - scattered
{{- if .enable_monitoring}}
annotations:
prometheus.io/scrape: "true"
{{- end}}
{{- if .enable_monitoring}}
prometheus.io/port: "9090"
{{- end}}
replicas: {{if .replicas}}{{.replicas}}{{else}}3{{end}}
Or better, set defaults in metadata and use:
replicas: {{.replicas}}
Basic Substitution
Simple Variables
Dot Notation
Conditionals
Basic If Statement
If-Else
If-Else-If
Negation
Comparisons
Equality
Inequality
Comparison Operators
Logical Operators
And
Or
Complex Conditions
Whitespace Control
Default Behavior
Remove Whitespace
Whitespace Control Positions
Practical Example
Comments
Template Comments
YAML Comments
String Functions
Print
Printf (Formatted Print)
Advanced Patterns
Nested Conditions
Multiple Conditions
Dynamic Labels
Common Patterns
Environment-Based Configuration
Feature Flags
Service Type Variations
Debugging Templates
Check Variable Values
Validate Syntax
Best Practices
Use Whitespace Control
Group Related Conditions
Provide Defaults in Logic
Next Steps