336 lines
10 KiB
Markdown
336 lines
10 KiB
Markdown
## Advanced Features
|
|
|
|
- [Import Configuration Parameters into Helmfile](#import-configuration-parameters-into-helmfile)
|
|
- [Deploy Kustomization with Helmfile](#deploy-kustomizations-with-helmfile)
|
|
- [Adhoc Kustomization of Helm Charts](#adhoc-kustomization-of-helm-charts)
|
|
- [Adding dependencies without forking the chart](#adding-dependencies-without-forking-the-chart)
|
|
|
|
### Import Configuration Parameters into Helmfile
|
|
|
|
Helmfile integrates [vals]() to import configuration parameters from following backends:
|
|
|
|
- AWS SSM Parameter Store
|
|
- AWS SecretsManager
|
|
- Vault
|
|
- SOPS
|
|
|
|
See [Vals "Supported Backends"](https://github.com/helmfile/vals#supported-backends) for the full list of available backends.
|
|
|
|
This feature was implemented in https://github.com/roboll/helmfile/pull/906.
|
|
If you're curious about how it's designed and how it works, please review the pull request.
|
|
|
|
### Deploy Kustomizations with Helmfile
|
|
|
|
You can deploy [kustomize](https://github.com/kubernetes-sigs/kustomize) "kustomization"s with Helmfile.
|
|
|
|
Most Kustomize operations are usually done with `kustomize edit` and can be done declaratively via Helm `values.yaml` files.
|
|
|
|
Under the hood, Helmfile transforms the kustomization into a local chart in a temporary directory so that it can be `helm upgrade --install`ed.
|
|
|
|
The transformation is done by generating (1)a temporary kustomization from various options and (2)temporary chart from the temporary kustomization.
|
|
|
|
An example pseudo code for the transformation logic can be written as:
|
|
|
|
```console
|
|
$ TMPCHART=/tmp/sometmpdir
|
|
$ mkdir -p ${TMPCHART}/templates
|
|
$ somehow_generate_chart_yaml ${TMPCHART}/Chart.yaml
|
|
|
|
$ TMPKUSTOMIZATION=/tmp/sometmpdir2
|
|
$ somehow_generate_temp_kustomization_yaml ${TMPKUSTOMIZATION}/kustomization.yaml
|
|
$ kustomize build ${TMPKUSTOMIZATION}/kustomization.yaml > ${TMPCHART}/templates/all.yaml
|
|
```
|
|
|
|
Let's say you have a `helmfile.yaml` that looks like the below:
|
|
|
|
```yaml
|
|
releases:
|
|
- name: myapp
|
|
chart: mykustomization
|
|
values:
|
|
- values.yaml
|
|
```
|
|
|
|
Helmfile firstly generates a temporary `kustomization.yaml` that looks like:
|
|
|
|
```yaml
|
|
bases:
|
|
- $(ABS_PATH_TO_HELMFILE_YAML}/mykustomization
|
|
```
|
|
|
|
Followed by the below steps:
|
|
|
|
- Running `kustomize edit set image $IMAGE` for every `$IMAGE` generated from your values.yaml
|
|
- Running `kustomize edit set nameprefix $NAMEPREFIX` with the nameprefix specified in your values.yaml
|
|
- Running `kustomize edit set namesuffix $NAMESUFFIX` with the namesuffix specified in your values.yaml
|
|
- Running `kustomize edit set namespace $NS` with the namespace specified in your values.yaml
|
|
|
|
A `values.yaml` file for kustomization would look like the below:
|
|
|
|
```yaml
|
|
images:
|
|
# kustomize edit set image mysql=eu.gcr.io/my-project/mysql@canary
|
|
- name: mysql
|
|
newName: eu.gcr.io/my-project/mysql
|
|
newTag: canary
|
|
# kustomize edit set image myapp=my-registry/my-app@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
|
|
- name: myapp
|
|
digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
|
|
newName: my-registry/my-app
|
|
|
|
# kustomize edit set nameprefix foo-
|
|
namePrefix: foo-
|
|
|
|
# kustomize edit set namesuffix -bar
|
|
nameSuffix: -bar
|
|
|
|
# kustomize edit set namespace myapp
|
|
namespace: myapp
|
|
```
|
|
|
|
At this point, Helmfile can generate a complete kustomization from the base kustomization you specified in `releases[].chart` of your helmfile.yaml and `values.yaml`,
|
|
which can be included in the temporary chart.
|
|
|
|
After all, Helmfile just installs the temporary chart like standard charts, which allows you to manage everything with Helmfile regardless of each app is declared using a Helm chart or a kustomization.
|
|
|
|
Please also see [test/advanced/helmfile.yaml](https://github.com/helmfile/helmfile/tree/master/test/advanced/helmfile.yaml) for an example of kustomization support and more.
|
|
|
|
### Adhoc Kustomization of Helm charts
|
|
|
|
With Helmfile's integration with Kustomize, not only deploying Kustomization as a Helm chart, you can kustomize charts before installation.
|
|
|
|
.. Hint:: The following fields can also specify files, in the same manner as
|
|
the `values` field.
|
|
|
|
Currently, Helmfile allows you to set the following fields for kustomizing the chart:
|
|
|
|
- [`releases[].strategicMergePatches`](#strategicmergepatches)
|
|
- `releases[].jsonPatches`
|
|
- [`releases[].transformers`](#transformers)
|
|
|
|
#### `strategicMergePatches`
|
|
|
|
You can add/update any Kubernetes resource field rendered from a Helm chart by specifying `releases[].strategicMergePatches`:
|
|
|
|
```
|
|
repositories:
|
|
- name: incubator
|
|
url: https://charts.helm.sh/incubator
|
|
|
|
releases:
|
|
- name: raw1
|
|
chart: incubator/raw
|
|
values:
|
|
- resources:
|
|
- apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: raw1
|
|
namespace: default
|
|
data:
|
|
foo: FOO
|
|
strategicMergePatches:
|
|
- apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: raw1
|
|
namespace: default
|
|
data:
|
|
bar: BAR
|
|
```
|
|
|
|
Running `helmfile template` on the above example results in a ConfigMap called `raw` whose `data` is:
|
|
|
|
```yaml
|
|
foo: FOO
|
|
bar: BAR
|
|
```
|
|
|
|
Please note that the second `data` field `bar` is coming from the strategic-merge patch defined in the above helmfile.yaml.
|
|
|
|
There's also `releases[].jsonPatches` that works similarly to `strategicMergePatches` but has additional capability to remove fields.
|
|
|
|
Please also see [test/advanced/helmfile.yaml](https://github.com/helmfile/helmfile/tree/master/test/advanced/helmfile.yaml) for an example of patching support and more.
|
|
|
|
#### `transformers`
|
|
|
|
You can set `transformers` to apply [Kustomize's transformers](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/configureBuiltinPlugin.md#configuring-the-builtin-plugins-instead).
|
|
|
|
Each item can be a path to a YAML or Go template file, or an embedded transformer declaration as a YAML hash.
|
|
|
|
It's often used to add common labels and annotations to your resources.
|
|
|
|
In the below example, we add common annotations and labels every resource rendered from the `aws-load-balancer-controller` chart:
|
|
|
|
```yaml
|
|
releases:
|
|
- name: "aws-load-balancer-controller"
|
|
namespace: "kube-system"
|
|
forceNamespace: "kube-system"
|
|
chart: "center/aws/aws-load-balancer-controller"
|
|
transformers:
|
|
- apiVersion: builtin
|
|
kind: AnnotationsTransformer
|
|
metadata:
|
|
name: notImportantHere
|
|
annotations:
|
|
area: 51
|
|
greeting: take me to your leader
|
|
fieldSpecs:
|
|
- path: metadata/annotations
|
|
create: true
|
|
- apiVersion: builtin
|
|
kind: LabelTransformer
|
|
metadata:
|
|
name: notImportantHere
|
|
labels:
|
|
foo: bar
|
|
fieldSpecs:
|
|
- path: metadata/labels
|
|
create: true
|
|
```
|
|
|
|
As explained earlier, `transformers` can be not only a list of embedded transformers, but also YAML or Go template files, or a mix of those three kinds.
|
|
|
|
```yaml
|
|
transformers:
|
|
# Embedded transformer
|
|
- apiVersion: builtin
|
|
kind: AnnotationsTransformer
|
|
metadata:
|
|
name: notImportantHere
|
|
annotations:
|
|
area: 51
|
|
greeting: take me to your leader
|
|
fieldSpecs:
|
|
- path: metadata/annotations
|
|
create: true
|
|
# YAML file
|
|
- path/to/transformer.yaml
|
|
# Go template
|
|
# The same set of template parameters as release values files templates is available.
|
|
- path/to/transformer.yaml.gotmpl
|
|
```
|
|
|
|
Please see https://github.com/kubernetes-sigs/kustomize/blob/master/examples/configureBuiltinPlugin.md#configuring-the-builtin-plugins-instead for more information on how to declare transformers.
|
|
|
|
### Adding dependencies without forking the chart
|
|
|
|
With Helmfile, you can add chart dependencies to a Helm chart without forking it.
|
|
|
|
An example `helmfile.yaml` that adds a `stable/envoy` dependency to the release `foo` looks like the below:
|
|
|
|
```yaml
|
|
repositories:
|
|
- name: stable
|
|
url: https://charts.helm.sh/stable
|
|
|
|
releases:
|
|
- name: foo
|
|
chart: ./path/to/foo
|
|
dependencies:
|
|
- chart: stable/envoy
|
|
version: 1.5
|
|
```
|
|
|
|
When Helmfile encounters `releases[].dependencies`, it creates another temporary chart from `./path/to/foo` and adds the following `dependencies` to the `Chart.yaml`, so that you don't need to fork the chart.
|
|
|
|
```yaml
|
|
dependencies:
|
|
- name: envoy
|
|
repo: https://charts.helm.sh/stable
|
|
condition: envoy.enabled
|
|
```
|
|
|
|
A Helm chart can have two or more dependencies for the same chart with different `alias`es. To give your dependency an `alias`, define it like you would do in a standard `Chart.yaml`:
|
|
|
|
```yaml
|
|
repositories:
|
|
- name: stable
|
|
url: https://charts.helm.sh/stable
|
|
|
|
releases:
|
|
- name: foo
|
|
chart: ./path/to/foo
|
|
dependencies:
|
|
- chart: stable/envoy
|
|
version: 1.5
|
|
alias: bar
|
|
- chart: stable/envoy
|
|
version: 1.5
|
|
alias: baz
|
|
```
|
|
|
|
which will tweaks the temporary chart's `Chart.yaml` to have:
|
|
|
|
|
|
```yaml
|
|
dependencies:
|
|
- alias: bar
|
|
name: envoy
|
|
repo: https://charts.helm.sh/stable
|
|
condition: bar.enabled
|
|
- alias: baz
|
|
name: envoy
|
|
repo: https://charts.helm.sh/stable
|
|
condition: baz.enabled
|
|
```
|
|
|
|
Please see #649 for more context around this feature.
|
|
|
|
After the support for adhoc dependency to local chart (#1765),
|
|
you can even write local file paths relative to `helmfile.yaml` in `chart`:
|
|
|
|
```yaml
|
|
releases:
|
|
- name: foo
|
|
chart: ./path/to/foo
|
|
dependencies:
|
|
- chart: ./path/to/bar
|
|
```
|
|
|
|
Internally, Helmfile creates another temporary chart from the local chart `./path/to/foo`, and modifies the chart's `Chart.yaml` dependencies to look like:
|
|
|
|
```yaml
|
|
dependencies:
|
|
- alias: bar
|
|
name: bar
|
|
repo: file:///abs/path/to/bar
|
|
condition: bar.enabled
|
|
```
|
|
|
|
Please read https://github.com/roboll/helmfile/issues/1762#issuecomment-816341251 for more details.
|
|
|
|
#### OCI chart dependencies
|
|
|
|
With Helmfile version v0.146.0 or later, you can add OCI chart to chart dependencies.
|
|
|
|
An example `helmfile.yaml` that adds a OCI chart dependency to the release `foo` looks like the below:
|
|
|
|
```yaml
|
|
releases:
|
|
- name: foo
|
|
chart: ./path/to/foo
|
|
dependencies:
|
|
- chart: oci://my-oci-registry/helm-repo/envoy
|
|
version: 1.5
|
|
```
|
|
|
|
### Lockfile per environment
|
|
|
|
In some cases it can be handy for CI/CD pipelines to be able to roll out updates gradually for environments, such as staging and production while using the same
|
|
set of charts. This can be achieved by using `lockFilePath` in combination with environments, such as:
|
|
|
|
```yaml
|
|
environments:
|
|
staging:
|
|
production
|
|
|
|
---
|
|
lockFilePath: .helmfile.{{ .Environment.Name}}.lock
|
|
|
|
releases:
|
|
- name: myapp
|
|
chart: charts/myapp
|
|
```
|