Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow helm to add external files to chart deployment #3276

Open
lenalebt opened this issue Dec 19, 2017 · 112 comments · May be fixed by #10077
Open

Allow helm to add external files to chart deployment #3276

lenalebt opened this issue Dec 19, 2017 · 112 comments · May be fixed by #10077

Comments

@lenalebt
Copy link

Hello,
currently Helm does not support including files that are not part of the chart to be included in the deployment of the chart (as far as I understand, due to security reasons, and since Tiller only has access to files inside the chart).

Our use case is adding some SSL certificates, as well as some license files, to the helm chart deployment. Our software runs on premises in our customer's data center, and we'd like to give them a helm chart to ease installation. The license files are custom per customer, so they cannot be included in the chart.

Of course, we can instruct our customer to untar the chart, place the files, and then deploy the chart directory, but that is cumbersome and error-prone.

Proposal: Add a flag, such as --include-file=foobar-license.conf that will include a file to the chart before sending it to tiller. This way, it would only happen upon explicit user request and not "under the hood".

In case I misunderstood something and there is an easy way to achive something similar, I'd be happy to hear about that :).

@cr4igo
Copy link

cr4igo commented Dec 20, 2017

Hi Lena,

Current way:
The current way to implement adding file-content is to use the "--values" n-dimensional-parameter when calling helm install. Placing every file (normal config values, SSL-stuff, license) in a separate YML file should provide better readability.

Lets assume we use "firstspirit" as chart repository name, that provides then the chart(s) to the customer. Then the customer can deploy your chart via the call:

helm install firstspirit/caas --values myvalues.yml,ssl.yml,foobar-license.yml

Within your chart you can now validate if all required keys have values set (ssl cert(s), license, ..).
The license file can be stored locally, and when sending to the kubernetes cluster they should be stored as kubernets secrets. For faster development rampup you can provide a pregenerated ssl zert as default value.

As another pros, the customer can automize the SSL cert generation by third-party tools and generate by himself the .yml files for setting your kubernetes secret values outside of Helm and passing the generated files to Helm for the "helm install" command.

Best regards,
Markus

@lenalebt
Copy link
Author

Hi Markus,
unsure if we understand each other correctly. To elaborate a little on my use case, this is what my chart contains currently:

...
{{ if .Files.Get "config/fs-license.conf" }}
file.fs-license.conf:               {{ .Files.Get "config/fs-license.conf"                                | b64enc }}
{{ else }}
{{ fail "you need to supply your license file! add 'fs-license.conf' to your chart 'config' directory." }}
{{ end }}
...

I wanted to not force users to provide base64-encoded strings in yaml files, but instead give the files directly. However, the files need to be part of the chart itself and cannot be given from the outside, hence this ticket.

@josdotso
Copy link

I have this exact need. My chart publishes a secret read from file at /keybase. This file is deliberately not in the chart.

I believe files for .Files.Get should not be assumed to be inside the chart:

https://github.com/kubernetes/helm/blob/master/pkg/chartutil/files.go#L32

@lenalebt
Copy link
Author

I am quite sure .Files.Get not being able to access the file system arbitrarily is a security feature, so I don't think the current behaviour is wrong - it just does not fulfill all use cases.

@balboah
Copy link
Contributor

balboah commented Jan 4, 2018

One alternative solution is to distribute your certs and licences as a separate helm release. Where you put them into config maps with a name that your service deployment knows about, use a configmap/secrets volume mount in your service deployment.

@balboah
Copy link
Contributor

balboah commented Jan 4, 2018

Maybe that was what @cr4igo already suggested :)

@jebbench
Copy link

We're having the same problem with a very similar use case:

We have certificates for Apple and Googles push notification services; we have different certificates for our test and production environments so we can't just bundle the certificate into the Chart (ignoring the security concerns around doing so); we would ideally like to be able to put the file path into the values file and have Helm load that file.

I don't have any good suggestions to how to tell Helm that the string in the values file is a relative file path - perhaps wrapping it in some sort of $file("path/goes/here") construct but it seems messy.

e.g.
values.yaml

apns:
  certificatePath: "./mycert.p12"

secret.yaml

...
data:
  apnsCertificate.p12: |-
    {{ Files.Get .Values.apns.certificatePath | b64enc }}

@lukasheinrich
Copy link

I think, this is a duplicate of #1754

@paravz
Copy link

paravz commented Apr 14, 2018

I don't think it's a duplicate, this is about allowing helm to access files on absolute paths outside of helm chart "root".

Example:

data:$
  dynamicvalues.json: |-$
{{- if .Files.Get (required "Helm Error: .Values.valuesfile is required" .Values.valuesfile) }}$
    {{ .Files.Get (.Values.valuesfile) }}$
{{- else }}$
{{ fail "Helm Error: specified .Values.valuesfile could not be read" }}$
{{- end }}$

This fails to render if pointing to files inside helm repo, ie:
helm --set valuesfile=/tmp/my-dynamic-file [...]

If the same file copied to helm root and pointed with relative path, the same command works.
Example below only works if pointing to files inside helm repo, anything outside fails,

@alonbl
Copy link

alonbl commented May 22, 2018

Hi,

I would like to suggest an approach similar to C-preprocessor... by default have the search path within the chart, however add --search-directories= parameter to allow additional directories. This will meet security requirements as sysadmin must specify where additional files resides, it will make the Files::glob work properly.

What do you think?

USE CASE

include additional set of files to configmap/secrets using .Files.Glob from directory outside of the chart package, without extracting the package.

PROBLEM

package must not escape authorized search directories.

SOLUTION

add --search-directories parameter to search files in additional directories specified by sysadmin, the files will be loaded into the fileset of the chart, available to the Files object.

@bacongobbler
Copy link
Member

bacongobbler commented Aug 14, 2018

Apologies for the delay on a response. The core team (including myself) has been focusing solely on getting an alpha release of Helm 3 out the door, so any development on significant contributions to Helm 2 have been much harder to dedicate resources for peer review and design work at this time.

The proposal in the OP (--include-file=foobar-license.conf) sounds like a reasonable solution if someone wants to tackle the feature! I'd highly suggest waiting until we have an alpha release of Helm 3 available before working on new feature work though; Helm 2 and Helm 3 development has diverged to a point where we will not be able to port over new Helm 2 features to Helm 3, which is why we've been hesitant about merging new features into recent releases and only working on bugfixes. Hope this helps!

@alexpirine
Copy link

Hello,

Any update on the status of this issue? How is it going for Helm 3?

@KlavsKlavsen
Copy link

I am asking too.. would very much like it for traefik ssl stuff f.ex. :)

@bacongobbler
Copy link
Member

bacongobbler commented Nov 1, 2018

AFAIK nobody from the community has started tackling this work for Helm 2.

@rtpro
Copy link

rtpro commented Mar 21, 2019

Hi, What's the latest on this topic? We are also looking for the requested behaviour. Thanks

@bacongobbler
Copy link
Member

Same as earlier. No update.

@luong-komorebi
Copy link

Still waiting for an update on this

@raftAtGit
Copy link

It should also be great if you provide an option like --include-folder=<path to folder> and Helm behaves like that folder is at the root of Helm chart. including a single file is not solving the issue in our case. there might hundreds of files and sub directories in that folder.

@bacongobbler bacongobbler added feature help wanted Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines. and removed proposal labels Apr 2, 2019
@bacongobbler
Copy link
Member

bacongobbler commented Apr 2, 2019

I'm marking this feature as "Help Wanted". It'd be great to have this feature, but we're busy re-working the architecture for Helm 3 that we don't have the time to focus on implementing new features like this one.

If you're interested in contributing this feature for Helm 3, please let us know so we can try to co-ordinate efforts/merge conflicts with the rest of the team.

Still waiting for an update on this

If there are further updates, we'll share them here.

Thanks!

@ytwig
Copy link

ytwig commented May 28, 2019

In case it helps anyone, i've managed to work around this limitation for my needs.
I'm kinda new to helm, so it might be a well known approach

My folder structure:

├───mainfests
│   └───[app_name]
│       ├───charts
├───[app_name]
│   └───resources
│       ├───config-prod.json
│       ├───config-staging.json

My problem:

I was trying to copy the content of the config files into a k8s configMap, but i've hit the limitation where i couldn't reference the config files, as they are external to the helm chart.

My solution:

I've used the set-file to copy the content of the config file

helm install --set-file ``configValues=./[app-name]/config/config_prod.json

And in my helm deployment yaml it's referenced like this:

apiVersion: v1
kind: ConfigMap
metadata:
  name: <config-name>
data:
  {{ printf "config_%s.json" .Values.envType }}: |-
  {{ .Values.configValues }}`

(edited multiple time to fix line breaks without success)

@pixelicous
Copy link

Such a needed feature for certificates primarily.. Else it gets far too complex for the job

@ecklm
Copy link

ecklm commented Mar 15, 2022

Ah, I get it now. I have misinterpreted the title.

@hixichen
Copy link

hixichen commented May 3, 2022

it would be great to see this feature becomes alive.

For the upstream helm chart, randomly, we need to add additional configmap or secrets to the charts.

@nilampatel-engineer
Copy link

I have this exact need. My chart publishes a secret read from file at /keybase. This file is deliberately not in the chart.

I believe files for .Files.Get should not be assumed to be inside the chart:

https://github.com/kubernetes/helm/blob/master/pkg/chartutil/files.go#L32

not able to access the link

@jasondamour
Copy link

Amazing how this simple ask can't be implemented over 5 years later. Helm really has some of the worse maintenance and management of any large-scale open source projects.

@PauloFerreira25
Copy link

+1

@kbirger
Copy link

kbirger commented Oct 18, 2022

Amazing how this simple ask can't be implemented over 5 years later. Helm really has some of the worse maintenance and management of any large-scale open source projects.

Do you know go? This IS an open source tool. Not a maintainer, but I'm sure they'd be happy to review a pr

@PauloFerreira25
Copy link

@kbirger PR is already open here
#8841

@alexpirine
Copy link

Amazing how this simple ask can't be implemented over 5 years later. Helm really has some of the worse maintenance and management of any large-scale open source projects.

Let’s stop making software and grow potatoes instead, so we can stop blaming each other and rather express our frustrations to gods of rain and sunshine.

@PauloFerreira25
Copy link

PauloFerreira25 commented Oct 18, 2022

@alexpirine
Please read this PR and see if it's not frustrating that something that is already ready, and required by many people, not be incorporated for any reason.
#8841

@alexpirine
Copy link

@alexpirine
Please read this PR and see if it's not frustrating that something that is already ready, and required by many people, not be incorporated for any reason.
#8841

I myself wanted this back in 2018 and commented here. I gave up on waiting anything.

I can only give a very general unsolicited advice: just find out another way to do things.

You can’t wait for another five years. Helm might very well be dead by that time and replaced by something newer and fancier (there are already 2 or 3 good candidates).

And we will have other issues. We are constantly creating new problems for ourselves by creating new technology.

@PauloFerreira25
Copy link

@alexpirine
"I can only give a very general unsolicited advice: just find out another way to do things."
I have another way of doing it, not as good as if it was done by the helm. But I have hope.

@Eeemil
Copy link

Eeemil commented Oct 18, 2022

Let’s stop making software and grow potatoes instead, so we can stop blaming each other and rather express our frustrations to gods of rain and sunshine.

I sometimes wish I was a farmer instead. 👨‍🌾

I can only give a very general unsolicited advice: just find out another way to do things.

You can’t wait for another five years. Helm might very well be dead by that time and replaced by something newer and fancier (there are already 2 or 3 good candidates).

I managed to circumvent my need for including files by using a symlink to whatever file I needed (outside of the chart) and then reference it with {{ tpl (.Files.Get "symlink-to-directory-with-stuff/snippets/very-secret-thing.yaml") . -}}. It's a rather ugly hack and it probably only ever works when referencing a chart on the local file system.

The chart looks something like

├── Chart.yaml
├── symlink-to-directory-with-stuff -> ../../../includes/
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── ingress.yaml
│   ├── pdb.yaml
│   └── service.yaml
└── values.yaml

And running a helm upgrade produces a warning

walk.go:74: found symbolic link in path: /path/to/chart/symlink-to-directory-with-stuff resolves to /somewhere/outside/of/the/chart/includes. Contents of linked file included and used

It works, but it really makes you wish you were a potato farmer instead.

@PauloFerreira25
Copy link

@Eeemil
This is a great solution when you have a local helm.
But for helm in a repository, it won't really work.
Thank you so much for sharing your "workaround".

@joejulian joejulian added help wanted Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines. in progress and removed help wanted Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines. labels Oct 18, 2022
@vlushn
Copy link

vlushn commented Oct 20, 2022

git repositories support symlinks, though unsure how well they are supported outside of *nix.

@MaesterZ
Copy link

MaesterZ commented Nov 1, 2022

This would be great also because in some cases, you create helm charts to have a whole software stack setup the right way and have the end user bring his own configuration (BYOC maybe? 😅), a bit like the BYOL model. Would allow to bring a "flat" file, potentially templated out from another software. Kubernetes is already complex enough for most people, if you add Helm, the step to get into the ecosystem is quite high IMO.

@wrenkredhat
Copy link

Hello,
i have another as i believe very significant use case for that.

I do render ALL my Manifests in a subchart knowing how to package towards the Cluster. However there is one artefact -- an OpenApiSpec -- which is to be delivered by a secret. But for the users of this chat there is no need to know how push this information into the cluster -- all they actually need is a values.yaml and the open-api-spec.yaml for this Service.
the subschart then can reach out into the parent's helm-directory and wrap the OpenApiSpec into -- whatever is needed.
so my UC is accessing files of the parent-chart from the subchart.
Thank you

iblazhko added a commit to iblazhko/es-replicator that referenced this issue Apr 24, 2023
When we need to use custom JS transform in Replicator, we specify

    transform:
      type: js
      config: ./transform.js

in replicator configuration.

Problem is that this configuration references an external file
that is currently not in Helm chart. Helm does not allow to
mount external files into pod at the time of the deployment,
see Helm issue <helm/helm#3276>.

This change adds a `transform.js` file into Helm chart that
we can reference in our configuration during deployment. the content
if this file is set from chart values, and we can overwrite this
during installation.

Bu default, the transform file is not used and the content of
`transform.js` is empty.

To use the transform, we need to overwrite `transform` section
in application configuration, and overwrite `transform.js` file
itself:

    helm install replicator-with-transform \
      es-replicator/es-replicator \
      --values values.yml \
      --set-file transformJs=./local-transform.js

`values.yml` should overwrite `transform` section:

    transform:
      type: js
      config: ./transform.js

Local file `local-transform.js` should define transformations / filters
as per <https://replicator.eventstore.org/docs/features/transforms/js/>.
@yywing
Copy link

yywing commented May 17, 2023

PR in: #10077

Unfortunately: #10077 (comment)

@afernandez-01
Copy link

+1

@hamadodene
Copy link

hamadodene commented May 21, 2024

I read in many comments that the problem can be solved using a syslink.
I'm using argocd and my config is configured on gitlab. Having multiple applications, I have a single base helm chart that is used as a dependency by all applications:
something like:

apiVersion: v2
name: example-app
dependencies:
   - name: base-chart
     version: "0.1.0"
     repository: https://gitlab/helm/stable

In the base-chart I used {{ (.Files.Glob "configMap/*").AsConfig | indent 2 }}
but it is actually not read since that folder is located outside. Can anyone explain to me better how I can manage this thing with syslinks?
Thanks,

@hamadodene
Copy link

hamadodene commented May 24, 2024

I solve my problem in argocd using the plugin https://github.com/crumbhole/argocd-lovely-plugin anche patching with kustomize+ helm...
Maybe using kustomize + helm can help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment