{"id":21006220,"url":"https://github.com/derlin/helmfile-intuitive-values-handling","last_synced_at":"2025-06-27T23:02:38.541Z","repository":{"id":151664256,"uuid":"501982867","full_name":"derlin/helmfile-intuitive-values-handling","owner":"derlin","description":"How to manage values (globals, environment, release-specific) intuitively within helmfile","archived":false,"fork":false,"pushed_at":"2022-06-20T15:24:51.000Z","size":5,"stargazers_count":26,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-13T14:43:34.805Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://blog.derlin.ch/helmfile-a-simply-trick-to-handle-values-intuitively","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/derlin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-10T09:32:00.000Z","updated_at":"2025-03-10T15:15:51.000Z","dependencies_parsed_at":null,"dependency_job_id":"528f436f-079f-4d4e-a8f2-9bee7c0cfc2c","html_url":"https://github.com/derlin/helmfile-intuitive-values-handling","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/derlin/helmfile-intuitive-values-handling","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/derlin%2Fhelmfile-intuitive-values-handling","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/derlin%2Fhelmfile-intuitive-values-handling/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/derlin%2Fhelmfile-intuitive-values-handling/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/derlin%2Fhelmfile-intuitive-values-handling/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/derlin","download_url":"https://codeload.github.com/derlin/helmfile-intuitive-values-handling/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/derlin%2Fhelmfile-intuitive-values-handling/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262347440,"owners_count":23296892,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-19T08:49:59.313Z","updated_at":"2025-06-27T23:02:38.518Z","avatar_url":"https://github.com/derlin.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# How to handle helmfile values nicely\n\n[helmfile](https://github.com/helmfile/helmfile) is a very powerful tool, but his way of handling release values is daunting for the beginners (and experts). I propose here a simple pattern to handle values, that is completely generic, intuitive and works in all situations.\n\n\u003cp align=center\u003e\n \u003cb\u003eRead the article ! \u003c/b\u003e\u003cbr\u003e\n \u003ca href=\"https://community.ops.io/derlin/helmfile-a-simple-trick-to-handle-values-intuitively-50cb\"\u003e\u003cb\u003e 👉 ✨ helmfile: a simple trick to handle values intuitively ✨ 👈\u003c/b\u003e\u003c/a\u003e\n\u003c/center\u003e\n\n## TL;DR\n\nThis repo reproduces the way values are handled in umbrella charts (Helm Charts with sub-charts).\n\n**If you don't like to read** but want to experiment instead:\n- clone this repo,\n- customize the different release values by editing `environments/default.yaml`,\n- override values per environment by editing `environments/\u003cenvName\u003e.yaml` (available environements are `local` and `prod`),\n- see for yourself how your changes work by running: `helmfile -e \u003cenv\u003e write-values` and see the output.\n\nTo apply this in your helmfile:\n\n1. ensure you reference `env-magic.gotmpl` under *all* release values (`releases.\u003creleaseName\u003e.values`) and,\n2. ensure you reference both `default.yaml` and `\u003cenvName\u003e.yaml` files under `environments.\u003cenvName\u003e.values`.\n\nDone.\n\n--------------\n\n\u003c!-- TOC start --\u003e\n- [🐌 Before we start: what are values](#-before-we-start-what-are-values)\n- [👎 How helmfile handles values](#-how-helmfile-handles-values)\n  * [Values and global values](#values-and-global-values)\n  * [Value overrides per environment](#value-overrides-per-environment)\n- [👌 Handling values better in helmfile](#-handling-values-better-in-helmfile)\n  * [What it entails](#what-it-entails)\n  * [How it works](#how-it-works)\n\u003c!-- TOC end --\u003e\n\n## 🐌 Before we start: what are values\n\nValues are parameters passed to a Helm chart. In helmfile, all releases are instances of a given helm chart, that defines its parameters in a `values.yaml` file. Those parameters can be overridden using different mechanisms (`--set` and `--values` using `helm`).\n\nWe often distinguish between two kind of values:\n1. *release-specific values*: values that need to be set only for one release \n   (we will refer to then as simply *values* in this README), and\n2. *global values*: values that must be set in all charts, such as the `domain` or the URL to some kafka broker.\n   Global values are especially useful when most of the releases in a helmfile rely on a common library chart.\n\nFurthermore, some values may need to be set differently depending on the environment.\nWe can thus talk about *global values* and *global environment values*.\n\n## 👎 How helmfile handles values\n\n### Values and global values\n\nIn a helmfile, *values* can be overriden at the release level:\n```yaml\nreleases:\n  - name: foo\n    # ...\n    values:\n      - simple: value # raw value \n      - path/to/raw-yaml-file.yaml # values read as is from a file\n      - path/to/template-outputting-yaml.gotmpl # go template outputting valid YAML values\n```\n\nIn order to set *global values*, one has to reference the same values/file/template below each releases, as seen above. There is no built-in support per se.\n\n### Value overrides per environment\n\nWhen we need to set *environment values*, helmfile supports a `environments.\u003cenvName\u003e.values` property:\n```yaml\nreleases: [...]\nenvironments:\n   prod:\n     values:\n      - global: value # raw value \n      - path/to/raw-yaml-file.yaml # values read as is from a file\n      - path/to/template-outputting-yaml.gotmpl # go template outputting valid YAML values\n```\n\nHowever, unintuitively enough, this **doesn't set any value at all**, but simply makes them available to templates.\nThat is, in go templates attached to releases, the `.Values` will be populated with the environment values (on top of the other values defined at the release level), such that a template may do:\n```yaml\nglobal: {{ .Values | get \"global\" \"UNSET\" }}\n```\nNotice the convoluted syntax, which is necessary because `global` may be undefined in other environments.\n\nWhen all environment values are meant to be global, one trick is to pass the following template inline: `{{ toYaml  .Values | nindent 10 }}`.\n\nTake this helmfile for example:\n```yaml\nreleases:\n  - name: foo\n    # ... reference some chart here\n    values:\n      - release-specific: check\n      - {{ toYaml .Values | nindent 10 }} # \u003c-- output all values (env + normal)\nenvironments:\n   prod:\n     values:\n       - env-prod: check\n```\nThe output of `helmfile -e prod write-values` will be:\n```yaml\nrelease-specific: check\nenv-prod: check\n```\n\nThis is nice for global environment values, but what about release-specific ones ?\nWell, there is no way around writing a specific template for each release... Or is there ?\n\n## 👌 Handling values better in helmfile\n\nIn this repository is shown a simpler way of handling values in helmfile, that doesn't require release-specific templates and covers all value types (global/specific, per environment).\n\nBasically, it reproduces the way values are handled in umbrella charts (Helm Charts with subcharts).\n\n### What it entails\n\nThe idea is:\n\n* define release-specific values in `environments/default.yaml`, under the release name;\n* define global values in `environments/default.yaml`, under `global`;\n* for environment values, use the same logic, but in a different file (e.g. `environments/\u003cenvName\u003e.yaml`).\n\nFor this pattern to work:\n\n1. all environments must reference `environments/default.yaml`, plus their specific file. This is also necessary for the default environment ! However, in this case, only the default file is listed.\n2. all releases must reference `env-magic.gotmpl` in their `values`. To simplify and keep it DRY, you can use YAML anchors (see the example `helmfile.yaml`).\n\nThat is, you should have something like this:\n```yaml\nreleases:\n  - name: foo\n    # ...\n    values:                    # this block should be under all releases\n      - \u0026env env-magic.gotmpl  # \u003c- the magic\n\nenvironments:\n  default:\n    values:\n      - environments/default.yaml  # always reference the default values files\n  prod:\n    values:\n      - environments/default.yaml\n      - environments/prod.yaml     # apply prod values on top of default\n```\n\nNote that the actual name of the files do not matter, of course.\n\n### How it works\n\nAll the magic comes from the `env-magic.gotmpl` file, which consists of one single line:\n```go\n{{ merge (.Values | get .Release.Name  dict) (.Values | get \"global\" dict) | toYaml }}\n```\n\nSince helmfile merges environment values and normal values automatically and makes them available through `.Values` in templates, the only thing left to do is to select only the values for the current release (`.Release.Name`),\nand the global values (`global`). We then merge the two, giving precedence to the release-specific values, \nand render them as YAML.](https://community.ops.io/derlin/helmfile-a-simple-trick-to-handle-values-intuitively-50cb)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fderlin%2Fhelmfile-intuitive-values-handling","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fderlin%2Fhelmfile-intuitive-values-handling","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fderlin%2Fhelmfile-intuitive-values-handling/lists"}