Overview
Reading the werf configuration, werf uses a built-in Go template engine (text/template) and expands the function set with Sprig and werf functions.
When organizing the configuration, it can be split into separate files in template directory.
Built-in Go template features
To work effectively, we recommend you looking at all the features, or at least the following sections:
Sprig functions
The Sprig library provides over 70 template functions:
- String Functions.
- Integer Math Functions.
- Encoding Functions.
- Dictionaries and Dict Functions.
- Path and Filepath Functions.
- Others.
Among all functions, werf does not support the expandenv function and has its own implementation for the env function.
werf functions
various environments
.Env
The .Env variable allows organizing configuration for several environments (testing, production, staging, and so on) and switching between them by the --env=<environment_name> option.
In helm templates, there is the
.Values.werf.envvariable that can be used the same way
current commit information
.Commit.Hash
{{ .Commit.Hash }} provides current commit SHA. It’s best to avoid using .Commit.Hash if possible, since it might trigger many unneeded stage rebuilds.
.Commit.Date
{{ .Commit.Date.Human }} provides commit date in Human form.
{{ .Commit.Date.Unix }} provides commit date in Unix epoch form.
Example: rebuild whole image every month
image: app
from: ubuntu:22.04
git:
- add: /
to: /app
stageDependencies:
install:
- "*"
fromCacheVersion: {{ div .Commit.Date.Unix (mul 60 60 24 30) }}
shell:
beforeInstall:
- apt-get update
- apt-get install -y nodejs npm
install:
- npm ci
templating
include
The include function brings in another template, and then pass the results to other template functions.
Syntax:
{{ include "<TEMPLATE_NAME>" <VALUES> }}
Example: how to use a common configuration
project: my-project
configVersion: 1
---
image: app1
from: alpine:3.21
shell:
beforeInstall:
{{- include "(component) ruby" . }}
---
image: app2
from: alpine:3.21
shell:
beforeInstall:
{{- include "(component) ruby" . }}
{{- define "(component) ruby" }}
- gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
- curl -sSL https://raw.githubusercontent.com/rvm/rvm/master/binscripts/rvm-installer -o /tmp/rvm-installer
- bash -e /tmp/rvm-installer
- bash -lec 'rvm install 2.3.4'
- bash -lec 'rvm use --default 2.3.4'
- bash -lec 'gem install bundler --no-ri --no-rdoc'
- bash -lec 'rvm cleanup all'
{{- end }}
tpl
The tpl function allows evaluating string as a template inside a template.
Syntax:
{{ tpl "<STRING>" <VALUES> }}
<STRING>— the content of a project file, an environment variable value, or an arbitrary string.<VALUES>— the template values. If you use the current context,., all templates and values (including those described in the template directory files) can be used in the template.
Example: how to use project files as the werf configuration partials
{{ $_ := set . "BaseImage" "node:14.3" }}
project: app
configVersion: 1
---
{{ range $path, $content := .Files.Glob "**/werf-partial.yaml" }}
{{ tpl $content $ }}
{{ end }}
{{- define "common install commands" }}
- npm install
- npm run build
{{- end }}
image: backend
from: {{ .BaseImage }}
git:
- add: /backend
to: /app/backend
shell:
install:
- cd /app/backend
{{- include "common install commands" . | indent 2 }}
image: frontend
from: {{ .BaseImage }}
git:
- add: /frontend
to: /app/frontend
shell:
install:
- cd /app/frontend
{{- include "common install commands" . | indent 2 }}
environment variables
env
The env function reads an environment variable.
Syntax:
{{ env "<ENV_NAME>" }}
{{ env "<ENV_NAME>" "default_value" }}
By default, the use of the
envfunction is not allowed by giterminism (read more about it here)
project files
.Files.Exists
The function .Files.Exists checks existence of a file (regular/directory) in project and returns the result true or false.
Syntax:
{{ .Files.Exists "<FILE_PATH>" }}
By default, the use of files that have non-committed changes is not allowed by giterminism (read more about it here)
.Files.Get
The function .Files.Get gets a certain project file content.
Syntax:
{{ .Files.Get "<FILE_PATH>" }}
By default, the use of files that have non-committed changes is not allowed by giterminism (read more about it here)
Example: how to add a certain file to stapel image without git directive (shell)
project: my-project
configVersion: 1
---
image: app
from: alpine:3.21
shell:
setup:
- |
head -c -1 <<'EOF' > /etc/nginx/nginx.conf
{{ .Files.Get ".werf/nginx.conf" | indent 4 }}
EOF
.Files.Glob
The function .Files.Glob allows getting project files with a glob and working with their content.
The function supports shell pattern matching and **. The function results can be merged with the merge sprig function (e.g., {{ $filesDict := merge (.Files.Glob "glob1") (.Files.Glob "glob2")).
Syntax:
{{ .Files.Glob "<GLOB>" }}
By default, the use of files that have non-committed changes is not allowed by giterminism (read more about it here)
Example: how to add files by a glob to stapel image without git directive (shell)
project: my-project
configVersion: 1
---
image: app
from: alpine:3.21
shell:
install: mkdir /app
setup:
{{ range $path, $content := .Files.Glob "modules/*/images/*/{Dockerfile,werf.inc.yaml}" }}
- |
head -c -1 <<EOF > /app/{{ base $path }}
{{ $content | indent 4 }}
EOF
{{ end }}
.Files.IsDir
The function .Files.IsDir checks path is a directory and returns true or false.
Syntax:
{{ .Files.IsDir "<PATH>" }}
By default, the use of files that have non-committed changes is not allowed by giterminism (read more about it here)
others
required
The required function declares a particular values entry as required for template rendering. If the value is empty, the template rendering will fail with a user submitted error message.
Syntax:
value: {{ required "<ERROR_MSG>" <VALUE> }}
fromYaml
The fromYaml function decodes a YAML document into a structure.
Syntax:
value: {{ fromYaml "<STRING>" }}
Example: how to read YAML file and then use a value
{{- $values := .Files.Get "werf_values.yaml" | fromYaml -}} # or fromYaml (.Files.Get "werf_values.yaml")
from: {{- $values.image.from }}
toYaml
The toYaml function encodes a structure into YAML document.
Syntax:
{{ toYaml <STRUCTURE> }}
Example: insert configuration in yaml format
{{ $cmdList := list "cmd1" "cmd2" }}
shell:
install:
{{- $cmdList | toYaml | nindent 4 }} # returns "- cmd1\n - cmd2"
Template directory
Template files can be stored in a reserved directory (.werf by default) with the extension .tmpl (arbitrary nesting .werf/**/*.tmpl is supported).
Template files and the werf configuration file define a common context:
- Template file is a complete template and can be used with the include function by the relative path (
{{ include "directory/partial.tmpl" . }}). - The template defined with the
definefunction in one template file is available in any other, including the werf configuration file.
Example: how to use templates defined in a template file
{{ $_ := set . "RubyVersion" "2.3.4" }}
{{ $_ := set . "BaseImage" "alpine:3.21" }}
project: my-project
configVersion: 1
---
image: rails
from: {{ .BaseImage }}
shell:
beforeInstall:
{{- include "(component) mysql client" . }}
{{- include "(component) ruby" . }}
install:
{{- include "(component) Gemfile dependencies" . }}
{{- define "(component) Gemfile dependencies" }}
- mkdir -p /root/.ssh
- |
bash -ec '
set -e
ssh-keyscan github.com >> /root/.ssh/known_hosts
ssh-keyscan mygitlab.myorg.com >> /root/.ssh/known_hosts
'
- |
bash -lec '
set -e
source /etc/profile.d/rvm.sh
cd /app
bundle install --without development test --path vendor/bundle
'
{{- end }}
{{- define "(component) mysql client" }}
- apt-get update && apt-get install -y libmysqlclient-dev mysql-client g++
{{- end }}
{{- define "(component) ruby" }}
- gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
- curl -sSL https://raw.githubusercontent.com/rvm/rvm/master/binscripts/rvm-installer -o /tmp/rvm-installer
- bash -e /tmp/rvm-installer
- bash -lec 'rvm install {{ .RubyVersion }}'
- bash -lec 'rvm use --default {{ .RubyVersion }}'
- bash -lec 'gem install bundler --no-ri --no-rdoc'
- bash -lec 'rvm cleanup all'