helm-controller icon indicating copy to clipboard operation
helm-controller copied to clipboard

FEATURE: HelmRelease valueFiles (multiple sources)

Open cdenneen opened this issue 1 year ago • 8 comments

Currently the only valueFiles is at the chart spec. I would like to request the feature be added to add valueFiles at the HelmRelease spec level to reside alongside the values and valuesFrom maps.

The valueFiles at the HelmReleaseSpec would allow for passing multiple -f values.yaml files to the release. These files would reside in a GitRepository sourceRef which would allow to overcome the fact that you can't pass multiple files currently, the valueFiles in the chart must reside from within the chart itself, doing a kustomize configMapGenerator can't merge values.yaml because it's a string, configMapGenerator doesn't allow for more than k=v pairs (no nested YAML).

This support currently exists in ArgoCD: https://argo-cd.readthedocs.io/en/stable/user-guide/multiple_sources/#helm-value-files-from-external-git-repository

cdenneen avatar Nov 20 '23 17:11 cdenneen

You can have multiple sources in a configMapGenerator like so:

configMapGenerator:
  - name: my-values
    files:
      - values1.yaml=values1.yaml
      - values2.yaml=values2.yaml

And in the HelmRelease:

spec:
  valuesFrom:
    - kind: ConfigMap
      name: my-values
      valuesKey: values1.yaml
    - kind: ConfigMap
      name: my-values
      valuesKey: values2.yaml

stefanprodan avatar Nov 21 '23 07:11 stefanprodan

I know this means they need to reside next to release and can’t be referenced from other sources

cdenneen avatar Nov 21 '23 12:11 cdenneen

They don't need to to be next to a release, helm-controller gets the values from etcd.

stefanprodan avatar Nov 21 '23 12:11 stefanprodan

configMapGenerator has a lot of limitations besides the fact that it puts the yaml into a string. For example when you want to have environment specific or cluster specific values, I can't use postBuild.substitute to replace values:

apiVersion: builtin
kind: ConfigMapGenerator
metadata:
  name: podinfo-values
  namespace: ${flux_namespace}
files:
  - values.yaml=values.yaml
  - environment.yaml=../../environments/${environment}/addons/podinfo/values.yaml
  - cluster.yaml=../../bootstrap/clusters/${cluster_name}/addons/podinfo/values.yaml

So inefficiently you technically can have the following in the release itself:

apiVersion: builtin
kind: ConfigMapGenerator
metadata:
  name: podinfo-values
  namespace: ${flux_namespace}
files:
  - values.yaml=values.yaml
  - dev.yaml=../../environments/dev/addons/podinfo/values.yaml
  - qa.yaml=../../environments/qa/addons/podinfo/values.yaml
  - prod.yaml=../../environments/prod/addons/podinfo/values.yaml

I lose the ability to have one for each cluster unless I literally wrote out every cluster:

files:
...
  - clusterA.yaml=../../clusters/clusterA/addons/podinfo/values.yaml
  - clusterB.yaml=../../clusters/clusterB/addons/podinfo/values.yaml
...
  - clusterZ.yaml=../../clusters/clusterZ/addons/podinfo/values.yaml

allowing the valuesFiles in the HelmSpec allows to avoid this and since HelmRelease can take advantage of variable substitution the limitation based on configMap generation goes away.

One advantage configMapGenerator has right now that I'm unclear if valuesFiles would allow is the variable substitution inside those does work but I'd assume that when HelmRelease ran it should work.

The helm-controller should be able to mount the values.yaml (valuesFiles) from the gitRepo as it does for the release.yaml already in the /tmp/ directories so should be no reason it technically couldn't sourceRef the values files (by default it looks in relative path within same GitRepository it's using for the HelmRelease unless you specify a different GitRepository name and it would be relative to that one.

cdenneen avatar Nov 21 '23 15:11 cdenneen

The helm-controller should be able to mount the values.yaml (valuesFiles) from the gitRepo as it does for the release.yaml already in the /tmp/ directories so should be no reason it technically couldn't sourceRef the values files (by default it looks in relative path within same GitRepository it's using for the HelmRelease unless you specify a different GitRepository name and it would be relative to that one.

This is not how the helm-controller works. What actually happens is that the template from the HelmRelease gets applied to the cluster, which will make the source-controller produce a packaged chart using the definitions from the release. The helm-controller itself has at no point knowledge about the existence, context or files from the source used by the HelmChart, it just knows packaged charts.

hiddeco avatar Nov 21 '23 15:11 hiddeco

The helm-controller should be able to mount the values.yaml (valuesFiles) from the gitRepo as it does for the release.yaml already in the /tmp/ directories so should be no reason it technically couldn't sourceRef the values files (by default it looks in relative path within same GitRepository it's using for the HelmRelease unless you specify a different GitRepository name and it would be relative to that one.

This is not how the helm-controller works. What actually happens is that the template from the HelmRelease gets applied to the cluster, which will make the source-controller produce a packaged chart using the definitions from the release. The helm-controller itself has at no point knowledge about the existence, context or files from the source used by the HelmChart, it just knows packaged charts.

@hiddeco are you confusing the valuesFiles from the chart spec with the recommendation here of adding one to the HelmReleaseSpec? The request here is for the HelmReleaseSpec to have a valuesFiles added to it's spec so it can reference other "values.yaml" from other locations (same GitRepository, another GitRepository, Bucket, etc).

For example if we have addons repo we could have defaults like values.yaml and ${environment}.yaml but you could leverage a tenant source GitRepository which houses their specific changes of values.yaml

So when they do a HelmRelease to their tenant (namespace) it could pull in the defaults from platform team and then leverage their specific overrides (similar to what we could do at a ${CLUSTER_NAME} values.yaml level). Obviously a tenant wouldn't have write access to the addons repo but they would to their own repo for overrides.

This isn't allowing HTTPS urls for values.yaml (which I think was removed in the past for security reasons) just allows different values.yaml sources which are still in the construct of source-controller's control.

cdenneen avatar Nov 21 '23 15:11 cdenneen

basically would be something like helm install releasename repo/chartname -f /tmp/gitrepostory-hash/path/to/values.yaml -f /tmp/gitrepository2/path/to/values.yaml -f /tmp/bucket-hash/path/to/values.yaml

cdenneen avatar Nov 21 '23 16:11 cdenneen

Today, if you want to have a values.yaml in Git and feed it into a HelmRelease as values, you need a few things:

  • a GitRepository (of course)
  • something to turn this fe into a ConfigMap : a kustomization.yaml with a configMapGenerator, and a FluxCD Kustomization
  • use the ConfigMap in HelmRelease.spec.valuesFrom[]

I would concur with @cdenneen that having the ability to directly refer to a path in a GitRepository would improve a lot the ease of doing such things.

Additionally, having the same ability for OCIRepositories would also be something very nice to have (have a way to point to a path under an OCIRepository in HelmRelease.spec.valuesFrom[]).

tmmorin avatar Jan 05 '24 16:01 tmmorin