#helmfile (2022-07)
Questions and discussion around helmfile https://github.com/roboll/helmfile and https://github.com/cloudposse/helmfiles
Archive: https://archive.sweetops.com/helmfile/
2022-07-04
hello all, I have a question. I have 2 charts and I move 1 secret from 1 chart to another. I do the kubectl patch and change the annotations to able to do helmfile apply on the chart where I copied the secret. when I do the apply on the chart from I moved the secret I see it deletes the secret does not check the annotation. Is it a bug or known issue ?
hey! which annotation are you referring?
thanks! does it work if you tried it without helmfile? i mean, does it reproduce if you upgraded the release which is the new owner of the secret, by running helm upgrade
rather than helmfile apply
?
a bit more context- helmfile calls helm upgrade
for upgrading releases. so if one thing doesn’t work with helm upgrade
, it won’t work with helmfile apply
.
Will check. It works if I delete all sh.helm.release.v1.appname.vx file. that contains the last deployed data and I gues that i sthe problem as well. so if I delete a secret but diff will find it in the release file on cluster it will delete that secret…
2022-07-05
Hello,
Are we still using [quay.io/roboll/helmfile](http://quay.io/roboll/helmfile)
for docker images? I cannot find v0.145.0
(released 6 days ago). Am I missing something?
our release automation was messed up! it’s now fixed and you should see images uploaded since v0.145.2 https://github.com/helmfile/helmfile/issues/207#issuecomment-1175798519
Actually quay.io isn’t used anymore. New org releases available at ghcr.io https://github.com/helmfile/helmfile/pkgs/container/helmfile
2022-07-06
I’m wondering if release templates work with environments:
I tried all possible syntaxes - nothing seems to work. Probably, I’m wrong conceptually.
You can even use helmfile templates to render release templates from environment values. So probably you are conflating the two- like you are trying to refer to environment values from a release template?
I think you are right.
It seems it’s not the problem of environments:
itself. Tried without it - still have some unmarshall errors.
I’m not sure if gotpl is supported in release templates. This is more likely the thing
My template is
templates:
sharedService: &sharedService
chart: chartmuseum/{{ .Release.Name }}
namespace: {{ .Environment.Name }}
missingFileHandler: Warn
labels:
tier: service
type: shared-service
values:
- config/{{ .Release.Name }}/values.yaml.gotpl
And in values.yaml.gotpl I have {{ .Values }} and {{ .Environments }} references
What we are trying to achieve is to improve readability and maintainability of our helmfile by reducing the number of lines (we have ~4000 lines of code). Trying out different approaches. But we need to keep environments: functionality and environments files as they are basically the interface for developers. We tried the first when each release has its own helmfile. From one hand it looks better, from another - if we need to fix a common thing we need to jump from file to file and we have like 50 of them. And to deploy them all at once we need either helmfiles:
and a list of all the references or helmfile.d
. We keep environments values in one file per environment when each release has its own key:
service1:
parameter1: value1
service2:
parameter1: value1
...
The second approach is to utilise the release template functionality and to put release values to separate files and keep environmnets values as it is.
You can even use helmfile templates to render release templates from environment values.
Could you, please, elaborate. I think I didn’t get this right:)
Thanks! A quick response to only a part of your info
config/{{ .Release.Name }}/values.yaml.gotpl
This will never work as you ight have intended. Such helmflie-level template expressions are rendered even before each so-called release template is rendered. At the time of helmfile-level templating, there’s no Release.Name
… as it’s rendering the tempalte in the context of the whole helmfile.yaml, not each release defined inside it. So you saw config/{{ .Release.Name }}/values.yaml.gotpl
to be actually translated to config//valules.yaml.gotmpl
? Then yes, it’s working as intended at least.
You may have some luck if it was written like
valueTemplates:
- {{` config/{{ .Release.Name }}/values.yaml.gotpl `}}
The key: Don’t let the helmfile-level template to evaluate {{.Release.Name}}
yet.
{{
`
// After probably two years since the feature had been implmemented, this two-phase go template rendering pipeline turned out to be too hard for anyone to understand fully That’s why I’m currently investigating possibilities to add Starlark support for writing dynamic helmfile config. With that you use a regular python-like program that is run once to produce a helmfile.yaml of your preference, instead of two-phase go template + yaml that is hard to understand
Sorry, my example might confuse you. My templates:
block in the recent try was located in the separate file and then in helmfile I had {{ readFile "template.yaml" }}
. Before that I also tried to define templates:
in helmfile with the following syntax
templates:
sharedService: &sharedService
chart: chartmuseum/{{`{{ .Release.Name }}`}}
namespace: {{`{{ .Environment.Name }}`}}
missingFileHandler: Warn
labels:
tier: service
type: shared-service
values:
- config/{{`{{ .Release.Name }}`}}/values.yaml.gotpl
But no luck.
In that case I think it worked only for chart
(Did it?
I slightly remember that someone contributed valuesTemplate
and namespaceTemplate
that are rendered by release template
so i guess this may work
chart: chartmuseum/{{`{{ .Release.Name }}`}}
namespaceTemplate: {{`{{ .Environment.Name }}`}}
missingFileHandler: Warn
labels:
tier: service
type: shared-service
valuesTemplate:
- config/{{`{{ .Release.Name }}`}}/values.yaml.gotpl
Cool. It seems valuesTemplate:
is the solution. However namespaceTemplate doesn’t work:
err: failed to read helmfile.yaml: reading document at index 1: yaml: unmarshal errors:
line 5: field namespaceTemplate not found in type state.TemplateSpec
line 5: field namespaceTemplate not found in type state.ReleaseSpec
line 5: field namespaceTemplate not found in type state.ReleaseSpec
line 5: field namespaceTemplate not found in type state.ReleaseSpec
helmfile version v0.145.2
And I also had to add this yaml separator ---
to make it work:
helmDefaults:
verify: false
wait: false
timeout: {{ env "WAIT_TIMEOUT" | default 600 }}
recreatePods: false
force: false
environments:
default:
values:
- default.yaml
---
{{ readFile "template.yaml" }}
releases:
...
And I also had to add this yaml separator — to make it work:
Nice! Yeah it’s generally recommended to always add ---
betwen environments and other configs
owever namespaceTemplate doesn’t work:
Sorry Not sure where my memory came from!
Yeah it’s generally recommended to always add ---
betwen environments and other configs
Good to know. We had never had any problems without it before these experiments:)
You’d ever get bitten by it only after you start using environments to dynamically generate releases Maybe that’s the case for you too?
Not sure what you mean by dynamically generate. We have plenty of {{ if .Environment.Name }}
and templetized installed:
blocks:)
Without ---
, helmfile renders the whole helmfile.yaml using the empty Environments for the first time, so that it can finally read environments
defined in your templated helmfile.yaml.
It then “re-render”s the helmfile.yaml template by using the environments loaded by the prev step, so that the template result might be what you expected.
This breaks when the helmfile.yaml template is “half” broken, in a way so that it doesn’t generate a valid YAML document after the first rendering step. Then environments
used for the second step becomes empty and you won’t get a valid result…
We call this “double-rendering”. I added it due to a community demand. 2 years later, the more I think about it, I cant stop saying it’s fundamentally broken.
With ---
you basically avoid relying on this double-rendering so everything is ok
and that’s why I proposed to deprecate using it without ---
in helmfile 1.0
https://github.com/helmfile/helmfile/blob/main/docs/proposals/towards-1.0.md#the-changes-in-10
I really don’t know who other than I and the original requestor of this feature knows how its supposed to work
IMHO, the most robust way to write a dynamic helmfile.yaml is, to not use templates
and release templates together. With all that said, your config would be more robust and easy to reason about if it’s rewritten like:
environments:
default:
values:
- default.yaml
---
{{ define "r" }}
- name: {{ .name }}
chart: chartmuseum/{{ .name }}
namespace: {{ .env }}
missingFileHandler: Warn
labels:
tier: service
type: shared-service
values:
- config/{{ .name }}/values.yaml.gotpl
{{* defaults *}}
verify: false
wait: false
timeout: {{ getOrNil . "timeout" | default 600 }}
recreatePods: false
force: false
{{ end }}
releases:
{{ template "r" (dict "name" "myapp" "env" .Environment.Name "timeout" 300) }}
{{ template "r" (dict "name" "mydb" "env" .Environment.Name) }}
{{ template "r" (dict "name" "mylogagent" "env" .Environment.Name) }}
or
r.tpl
:
- name: {{ .name }}
chart: chartmuseum/{{ .name }}
namespace: {{ .env }}
missingFileHandler: Warn
labels:
tier: service
type: shared-service
values:
- config/{{ .name }}/values.yaml.gotpl
{{* defaults *}}
verify: false
wait: false
timeout: {{ getOrNil . "timeout" | default 600 }}
recreatePods: false
force: false
helmfile.yaml
:
environments:
default:
values:
- default.yaml
---
releases:
{{ tpl (readFile "r.tpl") (dict "name" "myapp" "env" .Environment.Name "timeout" 300) }}
{{ tpl (readFile "r.tpl") (dict "name" "mydb" "env" .Environment.Name) }}
{{ tpl (readFile "r.tpl") (dict "name" "mylogagent" "env" .Environment.Name) }}
Thanks for the info. At the same time double-rendering allows us to achieve some things that are not possible without it:)
Probably we hadn’t faced issues with it before because we use double-rendering inside strings like
values:
- extEnv:
JAVA_OPTS: >
-Dserver.port={{`{{ .Values.container.port }}`}}
IMHO, the most robust way to write a dynamic helmfile.yaml is, to not use templates
and release templates together.
You meant not to use environments and release templates together, right?
Yep. Of course it’s just my recommendation- but you should be able to achieve anything that is possible with release template with define/template or readFile/tpl.
I tried both options and neither works if I want to have templates in
values:
- config/{{ .name }}/values.yaml.gotpl
For example if I have
environments:
default:
values:
- test: value
and in values.yaml.gotpl
test:
myVar: {{ .Values.test }}
then helmfile lint
executing helm lint myrelease
shows
Error: failed to parse /var/folders/pl/k4wqlgfj3cjf6b2p7qblq1200000gn/T/helmfile3449615217/default-print-service-values-57f59bc64: error converting YAML to JSON: yaml: invalid map key: map[interface {}]interface {}{".Values.test":interface {}(nil)}
For inline values second-pass rendering fails with
error calling tpl: template: stringTemplate:11:25: executing "stringTemplate" at <.Values.test>: map has no entry for key "Values"
Least privilege AWS IAM Terraformer
2022-07-08
2022-07-10
2022-07-25
:wave: Hello, team!
I’m a helmfile newbie, and I’m having a hard time using diff
:picard_fail:
On a helm, I used to do it this way:
helm diff upgrade grafana grafana/grafana --values grafana-values.yaml
How can I do such thing in helmfile ?
Thank you^
keep getting this error:
what version of helmfile and helm and diff you have ?
Helmfile: v0.145.2
diff: 3.1.3
use latest diff
helm plugin install https://github.com/databus23/helm-diff –version v3.5.0 and I had to set
export HELM_DIFF_COLOR=true
A helm plugin that shows a diff explaining what a helm upgrade would change
2022-07-27
hi everyone ! newbie on Helmfile i’ve started with this wonderful tools on sunday night.
atm i’m struggling with an issue about diff
and my values.yaml
#helmfile.yaml
templates:
default: &default
cleanupOnFail: true
chart: "{{`{{ .Release.Name }}`}}/{{`{{ .Release.Name }}`}}"
namespace: "{{`{{ .Release.Name }}`}}"
missingFileHandler: Warn
# This section allows the destruction of the namespaces when: helmfile destroy
hooks:
- events: ["postuninstall"]
showlogs: true
command: "kubectl"
args: ["delete", "namespaces", "{{`{{.Release.Namespace}}`}}"]
values:
- "environments/{{`{{ .Release.Name }}`}}/{{`{{ .Environment.Name }}`}}.yaml"
releases:
# - name: cert-manager
# <<: *default
# namespace: certs
- name: traefik
<<: *default
namespace: traefik
---
#environments/traefik/dev.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard
namespace: traefik
spec:
entryPoints:
- web
- websecure
routes:
- match: Host(`machin.com`) # Hostname to match
kind: Rule
services: # Service to redirect requests to
- name: api@internal # Special service created by Traefik pod
kind: TraefikService
first time i deploy everything seems good,,
but the next time i deploy with something changed into my dev.yaml
file
helmfile
do not sow any diff
and i see nothing in K8S
=> $ helmfile -e dev apply --skip-deps
any idea ?
On the first look, releases:
section should be placed into helmfile.yaml
instead of environments/traefik/dev.yaml
my bad , the section
releases:
# - name: cert-manager
# <<: *default
# namespace: certs
- name: traefik
<<: *default
namespace: traefik
is already in helmfile.yaml
do helm get values traefik
relfect dev.yaml changes after applying ?
When it is so -> issue is with chart + values combo. When no changes -> issue is somewhere in helmfile-related staff
(base) jmonnet in ~/Documents/CI/conccourse/ci-next/stack-k8s on jmonnet/confif-traefik-cert-manager ● ● λ kubectl get namespaces
NAME STATUS AGE
concourse-main Active 11h
kube-system Active 11h
kube-public Active 11h
kube-node-lease Active 11h
default Active 11h
monitoring Active 11h
portainer Active 11h
metallb-system Active 87m
traefik Active 52s
(base) jmonnet in ~/Documents//CI/conccourse/ci-next/stack-k8s on jmonnet/confif-traefik-cert-manager ● ● λ helm get values traefik
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /home/jmonnet/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /home/jmonnet/.kube/config
Error: release: not found
strange nothing in helm release
just add a namespace -n traefik
or use kubens
to switch current k8s context to this namespace
i forgot about my namespace ahah sorry ><
$ helm get values -n traefik traefik
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /home/jmonnet/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /home/jmonnet/.kube/config
USER-SUPPLIED VALUES:
ingressRoute:
dashboard:
enabled: false
ports:
web:
port: 80
websecure:
port: 443
securityContext:
capabilities:
add:
- NET_BIND_SERVICE
drop:
- ALL
readOnlyRootFilesystem: true
runAsGroup: 0
runAsNonRoot: false
runAsUser: 0
now it’s time to introduce changes into dev.yaml, run helmfile apply
and check if these changes hit to helm get values
result
change done on
websecure:
port: 444
in this case , diff
l plugin work , and i see my change in helm get values -n traefik traefik
but when i change
- match: Host(`toto.com`) # Hostname to match
there is no change in helmfile -e dev apply
and nothin in helm get values -n traefik traefik
I think dev.yaml is invalid. You cannot put raw yaml manifest into helm values usually
You have to find in the chart source code what helm chart variable corresponds to what you need to change. Then you’re ready to set this variable via helm values.
Helmfile is a helm wrapper in the first place.
Try to run helm
directly with --values
pointing to dev.yaml
, w/o helmfile
when you’re good with plain helm - you’re ready to put these values into helmfile, with some additional templating, env-specific variables and all the rest of helmfile nice features
2022-07-28
hello all, any idea about this issue?
panic: runtime error: slice bounds out of range [:1451] with capacity 729
The command(s) that were executed might be helpful. As far as code goes, it’s a Golang error where it is trying to get more indexes from an arr of smaller length
2022-07-29
Is there a way to apply labels to a namespace without using hooks?
Wondering the same thing.
Kyverno (https://kyverno.io/) + a Policy defined as a release in helmfile Recently they’ve added a possibility to mutate existing objects.
Actually, here is the link to an announcement with exactly this use case: https://nirmata.com/2022/06/03/kyverno-v1-7-0-mutate-and-generate-existing-resources-is-here/
Kyverno is a policy engine designed for Kubernetes
Nirmata announces the release of Kyverno v1.7.0 with the functionality of mutation and generation for existing policy resources for managing Kubernetes for DevOps efforts!