237 lines
9.4 KiB
Markdown
237 lines
9.4 KiB
Markdown
# Templating
|
|
|
|
Helmfile uses [Go templates](https://godoc.org/text/template) for templating your helmfile.yaml. While go ships several built-in functions, we have added all of the functions in the [Sprig library](https://godoc.org/github.com/Masterminds/sprig).
|
|
|
|
We also added the following functions:
|
|
|
|
* [`env`](templating_funcs.md#env)
|
|
* [`requiredEnv`](templating_funcs.md#requiredenv)
|
|
* [`exec`](templating_funcs.md#exec)
|
|
* [`envExec`](templating_funcs.md#envexec)
|
|
* [`readFile`](templating_funcs.md#readfile)
|
|
* [`readDir`](templating_funcs.md#readdir)
|
|
* [`readDirEntries`](templating_funcs.md#readdirentries)
|
|
* [`toYaml`](templating_funcs.md#toyaml)
|
|
* [`fromYaml`](templating_funcs.md#fromyaml)
|
|
* [`setValueAtPath`](templating_funcs.md#setvalueatpath)
|
|
* [`get`](templating_funcs.md#get) (Sprig's original `get` is available as `sprigGet`)
|
|
* [`getOrNil`](templating_funcs.md#getornil)
|
|
* [`tpl`](templating_funcs.md#tpl)
|
|
* [`required`](templating_funcs.md#required)
|
|
* [`fetchSecretValue`](templating_funcs.md#fetchsecretvalue)
|
|
* [`expandSecretRefs`](templating_funcs.md#expandsecretrefs)
|
|
* [`include`](templating_funcs.md#include)
|
|
|
|
More details on each function can be found at the ["Template Functions" page in our documentation](templating_funcs.md).
|
|
|
|
## Using environment variables
|
|
|
|
Environment variables can be used in most places for templating the helmfile. Currently this is supported for `name`, `namespace`, `value` (in set), `values` and `url` (in repositories).
|
|
|
|
Examples:
|
|
|
|
```yaml
|
|
repositories:
|
|
- name: your-private-git-repo-hosted-charts
|
|
url: https://{{ requiredEnv "GITHUB_TOKEN"}}@raw.githubusercontent.com/kmzfs/helm-repo-in-github/master/
|
|
```
|
|
|
|
```yaml
|
|
releases:
|
|
- name: {{ requiredEnv "NAME" }}-vault
|
|
namespace: {{ requiredEnv "NAME" }}
|
|
chart: roboll/vault-secret-manager
|
|
values:
|
|
- db:
|
|
username: {{ requiredEnv "DB_USERNAME" }}
|
|
password: {{ requiredEnv "DB_PASSWORD" }}
|
|
set:
|
|
- name: proxy.domain
|
|
value: {{ requiredEnv "PLATFORM_ID" }}.my-domain.com
|
|
- name: proxy.scheme
|
|
value: {{ env "SCHEME" | default "https" }}
|
|
```
|
|
|
|
### Note
|
|
|
|
If you wish to treat your enviroment variables as strings always, even if they are boolean or numeric values you can use `{{ env "ENV_NAME" | quote }}` or `"{{ env "ENV_NAME" }}"`. These approaches also work with `requiredEnv`.
|
|
|
|
### Useful internal Helmfile environment variables
|
|
|
|
Helmfile uses some OS environment variables to override default behaviour:
|
|
|
|
* `HELMFILE_DISABLE_INSECURE_FEATURES` - disable insecure features, expecting `true` lower case
|
|
* `HELMFILE_DISABLE_RUNNER_UNIQUE_ID` - disable unique logging ID, expecting any non-empty value
|
|
* `HELMFILE_SKIP_INSECURE_TEMPLATE_FUNCTIONS` - disable insecure template functions, expecting `true` lower case
|
|
* `HELMFILE_USE_HELM_STATUS_TO_CHECK_RELEASE_EXISTENCE` - expecting non-empty value to use `helm status` to check release existence, instead of `helm list` which is the default behaviour
|
|
* `HELMFILE_EXPERIMENTAL` - enable experimental features, expecting `true` lower case
|
|
* `HELMFILE_ENVIRONMENT` - specify [Helmfile environment](environments.md), it has lower priority than CLI argument `--environment`
|
|
* `HELMFILE_TEMPDIR` - specify directory to store temporary files
|
|
* `HELMFILE_UPGRADE_NOTICE_DISABLED` - expecting any non-empty value to skip the check for the latest version of Helmfile in [helmfile version](cli.md#version)
|
|
* `HELMFILE_GO_YAML_V3` - use *go.yaml.in/yaml/v3* instead of *go.yaml.in/yaml/v2*. It's `false` by default in Helmfile v0.x, and `true` in Helmfile v1.x.
|
|
* `HELMFILE_CACHE_HOME` - specify directory to store cached files for remote operations
|
|
* `HELMFILE_FILE_PATH` - specify the path to the helmfile.yaml file
|
|
* `HELMFILE_INTERACTIVE` - enable interactive mode, expecting `true` lower case. The same as `--interactive` CLI flag
|
|
* `HELMFILE_RENDER_YAML` - force helmfile.yaml to be rendered as a Go template regardless of file extension, expecting `true` lower case. Useful for migrating from v0 to v1 without renaming files to `.gotmpl`
|
|
* `HELMFILE_AWS_SDK_LOG_LEVEL` - configure AWS SDK logging level for vals library. Valid values: `off` (default, secure, case-insensitive), `minimal`, `standard`, `verbose`, or custom comma-separated values like `request,response`. See issue #2270 for details
|
|
* `HELMFILE_VALS_FAIL_ON_MISSING_KEY_IN_MAP` - enable strict mode for vals secret references. When set to `true` (or any value accepted by Go's `strconv.ParseBool` like `TRUE`, `1`), vals will fail when a referenced key does not exist in the secret map. Invalid values will cause an error when vals is initialized (when secret refs are first evaluated). Default is `false` (when unset or empty) for backward compatibility. See issue #1563 for details
|
|
|
|
|
|
## Templates
|
|
|
|
You can use go's text/template expressions in `helmfile.yaml` and `values.yaml.gotmpl` (templated helm values files). `values.yaml` references will be used verbatim. In other words:
|
|
|
|
* for value files ending with `.gotmpl`, template expressions will be rendered
|
|
* for plain value files (ending in `.yaml`), content will be used as-is
|
|
|
|
In addition to built-in ones, the following custom template functions are available:
|
|
|
|
* `readFile` reads the specified local file and generate a golang string
|
|
* `readDir` reads the files within provided directory path. (folders are excluded)
|
|
* `readDirEntries` Returns a list of [https://pkg.go.dev/os#DirEntry](DirEntry) within provided directory path
|
|
* `fromYaml` reads a golang string and generates a map
|
|
* `setValueAtPath PATH NEW_VALUE` traverses a golang map, replaces the value at the PATH with NEW_VALUE
|
|
* `toYaml` marshals a map into a string
|
|
* `get` returns the value of the specified key if present in the `.Values` object, otherwise will return the default value defined in the function
|
|
|
|
### Values Files Templates
|
|
|
|
You can reference a template of values file in your `helmfile.yaml` like below:
|
|
|
|
```yaml
|
|
releases:
|
|
- name: myapp
|
|
chart: mychart
|
|
values:
|
|
- values.yaml.gotmpl
|
|
```
|
|
|
|
Every values file whose file extension is `.gotmpl` is considered as a template file.
|
|
|
|
Suppose `values.yaml.gotmpl` was something like:
|
|
|
|
```yaml
|
|
{{ readFile "values.yaml" | fromYaml | setValueAtPath "foo.bar" "FOO_BAR" | toYaml }}
|
|
```
|
|
|
|
And `values.yaml` was:
|
|
|
|
```yaml
|
|
foo:
|
|
bar: ""
|
|
```
|
|
|
|
The resulting, temporary values.yaml that is generated from `values.yaml.gotmpl` would become:
|
|
|
|
```yaml
|
|
foo:
|
|
# Notice `setValueAtPath "foo.bar" "FOO_BAR"` in the template above
|
|
bar: FOO_BAR
|
|
```
|
|
|
|
## Refactoring `helmfile.yaml` with values files templates
|
|
|
|
One of expected use-cases of values files templates is to keep `helmfile.yaml` small and concise.
|
|
|
|
See the example `helmfile.yaml` below:
|
|
|
|
```yaml
|
|
releases:
|
|
- name: {{ requiredEnv "NAME" }}-vault
|
|
namespace: {{ requiredEnv "NAME" }}
|
|
chart: roboll/vault-secret-manager
|
|
values:
|
|
- db:
|
|
username: {{ requiredEnv "DB_USERNAME" }}
|
|
password: {{ requiredEnv "DB_PASSWORD" }}
|
|
set:
|
|
- name: proxy.domain
|
|
value: {{ requiredEnv "PLATFORM_ID" }}.my-domain.com
|
|
- name: proxy.scheme
|
|
value: {{ env "SCHEME" | default "https" }}
|
|
```
|
|
|
|
The `values` and `set` sections of the config file can be separated out into a template:
|
|
|
|
`helmfile.yaml`:
|
|
|
|
```yaml
|
|
releases:
|
|
- name: {{ requiredEnv "NAME" }}-vault
|
|
namespace: {{ requiredEnv "NAME" }}
|
|
chart: roboll/vault-secret-manager
|
|
values:
|
|
- values.yaml.gotmpl
|
|
```
|
|
|
|
`values.yaml.gotmpl`:
|
|
|
|
```yaml
|
|
db:
|
|
username: {{ requiredEnv "DB_USERNAME" }}
|
|
password: {{ requiredEnv "DB_PASSWORD" }}
|
|
proxy:
|
|
domain: {{ requiredEnv "PLATFORM_ID" }}.my-domain.com
|
|
scheme: {{ env "SCHEME" | default "https" }}
|
|
```
|
|
|
|
## Importing values from any source
|
|
|
|
The `exec` template function that is available in `values.yaml.gotmpl` is useful for importing values from any source
|
|
that is accessible by running a command:
|
|
|
|
A usual usage of `exec` would look like this:
|
|
|
|
```yaml
|
|
mysetting: |
|
|
{{ exec "./mycmd" (list "arg1" "arg2" "--flag1") | indent 2 }}
|
|
```
|
|
|
|
Or even with a pipeline:
|
|
|
|
```yaml
|
|
mysetting: |
|
|
{{ yourinput | exec "./mycmd-consume-stdin" (list "arg1" "arg2") | indent 2 }}
|
|
```
|
|
|
|
The possibility is endless. Try importing values from your golang app, bash script, jsonnet, or anything!
|
|
|
|
Then `envExec` same as `exec`, but it can receive a dict as the envs.
|
|
|
|
A usual usage of `envExec` would look like this:
|
|
|
|
```yaml
|
|
mysetting: |
|
|
{{ envExec (dict "envkey" "envValue") "./mycmd" (list "arg1" "arg2" "--flag1") | indent 2 }}
|
|
```
|
|
|
|
## Using .env files
|
|
|
|
Helmfile itself doesn't have an ability to load .env files. But you can write some bash script to achieve the goal:
|
|
|
|
```console
|
|
set -a; . .env; set +a; helmfile sync
|
|
```
|
|
|
|
Please see #203 for more context.
|
|
|
|
## Running Helmfile interactively
|
|
|
|
`helmfile --interactive [apply|destroy|delete|sync]` requests confirmation from you before actually modifying your cluster.
|
|
|
|
Use it when you're running `helmfile` manually on your local machine or a kind of secure administrative hosts.
|
|
|
|
For your local use-case, aliasing it like `alias hi='helmfile --interactive'` would be convenient.
|
|
|
|
Another way to use it is to set the environment variable `HELMFILE_INTERACTIVE=true` to enable the interactive mode by default.
|
|
Anything other than `true` will disable the interactive mode. The precedence has the `--interactive` flag.
|
|
|
|
## Running Helmfile without an Internet connection
|
|
|
|
Once you download all required charts into your machine, you can run `helmfile sync --skip-deps` to deploy your apps.
|
|
With the `--skip-deps` option, you can skip running "helm repo update" and "helm dependency build".
|
|
|
|
## `bash` and `zsh` completion
|
|
|
|
helmfile completion --help
|