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

Support for using {{ values }} within values.yaml #2133

Closed
DrEsteban opened this issue Mar 17, 2017 · 36 comments
Closed

Support for using {{ values }} within values.yaml #2133

DrEsteban opened this issue Mar 17, 2017 · 36 comments
Labels

Comments

@DrEsteban
Copy link

DrEsteban commented Mar 17, 2017

For example:

values.yaml

myApp:
  fooServiceName: {{ .Release.Name }}-foo-service

It seems like it would be a common pattern to incorporate {{ .Chart.Name }} or {{ .Release.Name }} into some variables. I got the following when I tried this:

error converting YAML to JSON: yaml: line 15: did not find expected key

Edit

To better illustrate my issue, consider a Chart with the following structure:

serviceA Chart directory structure:

charts/
    serviceB/
        templates/
            serviceB.yaml
        Chart.yaml
templates/
    serviceA.yaml
Chart.yaml
<etc...>

serviceB.yaml

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-service-b
spec:
  <...spec...>

Now, currently if I want serviceA to make calls to serviceB, I would have to do something like this:
serviceA.yaml

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-service-a
spec:
  containers:
    - env:
        - name: SERVICE_B_HOSTNAME
          value: {{ .Release.Name }}-{{ .Values.serviceB }}

values.yaml

serviceB: service-b

When I'd like to be able to do something like this:
serviceA.yaml

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-service-a
spec:
  containers:
    - env:
        - name: SERVICE_B_HOSTNAME
          value: {{ .Values.serviceB }}

values.yaml

serviceB: {{ .Release.Name }}-service-b

@technosophos
Copy link
Member

We have talked about supporting these as environment variables (e.g. $RELEASE_NAME, $CHART_NAME, etc).

However, the file that is passed into the template engine as a source of data for templates is itself not passed through the template engine. We almost definitely will not do that because it gets very confusing for users. It also breaks both standard YAML compatibility and backward compatibility with all existing Helm versions.

@thomastaylor312
Copy link
Contributor

@DrEsteban Did you have anything else you wanted to discuss or anything that @technosophos didn't address? If not, we are going to close this

@DrEsteban
Copy link
Author

DrEsteban commented Mar 30, 2017

@thomastaylor312 Apologies, yes one more question.

@technosophos Makes sense, thanks for the reasoning. As for the "environment variables support", do you mean automatically including $RELEASE_NAME or $CHART_NAME in the list of environment variables for a pod? Or something else? I'm just trying to determine how it relates to this issue of being able to specify values-within-values.

(Insert my recent edit from above)

Currently the templates of parent charts must adhere to/adopt the naming conventions of child charts, rather than allowing the parent templates to be independent of child naming conventions, and allowing Values.yaml to configure the entirety. If I decide to deploy serviceB separately from serviceA, I must edit the actual serviceA.yaml template to remove the {{ .Release.Name }} section instead of simply editing the values passed in.

Would the proposed "environment variables support" do anything to help with that?

@DrEsteban DrEsteban reopened this Mar 31, 2017
@DrEsteban
Copy link
Author

Oops, clicked the wrong button...

@markpundsack
Copy link

Sharing variables between parent and child is bad enough, but it gets worse when you have a dependency tree with children that need to share variables between them as peers.

e.g. for gitlab-bundle, I want a values.yaml something like":

baseDomain: your-domain.com
gitlab:
  ingress:
    hosts:
      - gitlab.{{ .Values.baseDomain }}
      - registry.{{ .Values.baseDomain }}
      - mattermost.{{ .Values.baseDomain }}
      - prometheus.{{ .Values.baseDomain }}
gitlab-runner:
  gitlabUrl: http://gitlab.{{ .Values.baseDomain }}

@dsanders1234
Copy link

I hit this problem trying to configure a default prometheus datasource for grafana using the charts under "stable". Grafana expects a url to the service, but I have no way of providing a release name prefix to the service name in the values yaml.

@mkjpryor-stfc
Copy link

mkjpryor-stfc commented Aug 21, 2017

@dsanders1234 I have exactly the same problem.

In fact, this is a problem any time you try to build a meta-package with packages from other repositories as requirements, as they tend (rightly!) to use {{ .Release.Name }} in their service names. This means you can't automatically configure the linkages.

It would be really nice to at least be able to access the release name and namespace in values.yaml. Without it, building meta-packages is pretty much impossible...

@paulczar
Copy link
Contributor

I have similar issues as well. I am trying to pass in a k8s dns for cassandra child package which is dependent on {{ .Release.Name }} and {{ .Release.Namespace }}.

@hobti01
Copy link
Contributor

hobti01 commented Oct 6, 2017

We are also having this issue to create "fully qualified" names for subcharts that are known to the parent and child. We can workaround this by (re)creating all the charts ourselves, but this defeats the purpose of packaged and shared charts.

@jrefi
Copy link

jrefi commented Oct 23, 2017

This issue is also affecting me in a similar manner to those above. I am trying to create a meta-package and need to pass a base host name to all subcharts to use to define their Ingress resources. Looks like I will have to rewrite all the charts I want to use myself.

@tlyng
Copy link

tlyng commented Oct 26, 2017

Also affecting me. I am having nginx-ingress as a dependency for one of my charts and I want to set up tcp forwarding, but the nginx-ingress require to know the service name upfront which I am not able to provide in values.yaml.

@zdannar
Copy link

zdannar commented Jan 12, 2018

  • 1 for this feature. Having to hard code values into additional templates for service discovery seems wrong. I am integrating vault with consul and need to know the consul service name which is set to -consul by the stable/consul chart.

@szwed
Copy link

szwed commented Jan 17, 2018

YAML also provides a handy feature called anchors, which let you easily duplicate
content across your document. Both of these keys will have the same value:

default: &default_title This Post Has No Title
title: *default_title

maps to:

18:40 $ helm install --dry-run --debug someapp/ |grep -i this
default: This Post Has No Title
title: This Post Has No Title

Doesn't allow for concatenation or more advanced combinations, but in some cases even this limited functionality may help a lot.

@mkjpryor-stfc
Copy link

mkjpryor-stfc commented Jan 17, 2018

@szwed: I am aware of YAML anchors, and have used them in the past for repeated bits of config. However, they don't help you with the main reason for this issue which is to get things like the release name without having to hard code it.

@romangithub1024
Copy link

We actually hit the same limitation and ended up implementing our own layer around Helm to glue services together. You can traverse the entire service tree by using {{ .Discovery }} variable and get access to dependent & peer services' data.

If you want to take a look, here is an example that brings up multiple instances kafka, spark, hdfs, zookeeper and twitter-based analytics around them. All from Helm charts:

@moneydance
Copy link

Is there a suggestion for this besides having a hardcoded release name? I'm also running into this issue.

@bradenwright
Copy link

I think this is the same as: #2492 and it looks like there is a pr mentioned over there: #3252

@dogik
Copy link

dogik commented Apr 24, 2018

I know that it is a bad solution, but as a workaround, we use gomplate (cli template processor) for values files and custom release name (in some cases it is even better - eg. when release name is as a partial hash of a commit). Might help someone.

Also, gomplate supports vault and other good stuff. Still not ideal solution though.

@bacongobbler
Copy link
Member

closing as a duplicate of #2492.

@DrEsteban
Copy link
Author

Interesting that my issue, filed several months earlier, was the "duplicate" ;) I understand... #2492 is a lot better described.

@zhangpengchen
Copy link

See also #2514.

:) Thankfully, latest Helm manual says how to achieve this.
https://helm.sh/docs/howto/charts_tips_and_tricks/#using-the-tpl-function

The trick is enclosing variable in " or in a yaml block |-, and than referencing it in a template as {{ tpl .Values.variable . }}
This seems to make Helm happy.

Example:

$ cat Chart.yaml | grep appVersion
appVersion: 0.0.1-SNAPSHOT-d2e2f42


$ cat platform/shared/t/values.yaml | grep -A2 image:
image: 
  tag: |-
    {{ .Chart.AppVersion }}


$ cat templates/deployment.yaml | grep image:
          image: "{{ .Values.image.repository }}:{{ tpl .Values.image.tag . }}"


$ helm template . --values platform/shared/t/values.betradar.yaml | grep image
          image: "docker-registry.default.svc:5000/namespace/service:0.0.1-SNAPSHOT-d2e2f42"
          imagePullPolicy: Always
      image: busybox

Otherwise there is an error thrown..

$ cat platform/shared/t/values.yaml | grep -A1 image:
image: 
  tag: {{ .Chart.AppVersion }}

1 $ helm template . --values platform/shared/t/values.yaml | grep image
Error: failed to parse platform/shared/t/values.yaml: error converting YAML to JSON: yaml: invalid map key: map[interface {}]interface {}{".Chart.AppVersion":interface {}(nil)}

Thanks @MilanMasek that quote save my hours.

@TBBle
Copy link
Contributor

TBBle commented Jul 29, 2020

For people still tracking this request, the current way forward appears to be #6876, which is apparently under review.

@TBBle
Copy link
Contributor

TBBle commented Aug 29, 2020

There's also #8580 which is a similar approach to the problem as #6876. See #8576 for some discussion on the differences.

aure-olli added a commit to aure-olli/helm that referenced this issue Sep 3, 2020
This is the 3rd and last PR splitted from helm#6876, and should be merged after helm#8677 and helm#8679

There have been many requests for a way to use templates for `values.yaml` (helm#2492, helm#2133, ...). The main reason being that it's currently impossible to derive the values of the subcharts from templates. However, having templates in `values.yaml` make them unparsable and create a "chicken or the egg" problem when rendering them.

This PR offers an intuitive solution without such a problem: an optional `values/` directory which templates are rendered using `values.yaml`, and then merge them with it. Those `values/` templates are only required for specific cases, work the same way as `templates/` templates, and `values.yaml` will remain the main parsable source of value.

Values evaluation is now made in 2 step. First the `values.yaml` file is read. Then the `values/***.yaml` files are rendered using those values (`values/_***.tpl` files ara still allowed as helpers), and are used to update the values.

For each chart and subchart, the following steps are performed:
1. If the chart has a parent, parent sub-values and global values are retrieved.
2. The chart values are coalesced with the retrieved value, the chart values are not authoritative.
3. The chart `values/` templates are rendered, the same way `templates/` templates are. The values are not updated during this step.
4. The values are updated with the rendered `values/` templates, sorted by name. The `values/` templates are authoritative and can replace values from the chart `values.yaml` or the previous `values/` templates.
5. The dependencies conditions and tags are evaluated over the updated values, and disabled dependencies are removed.
6. The same process is performed on enabled dependencies.

Once values are recursively updated, and once import values are treated on the enabled dependencies, those values are used for templates rendering.

Signed-off-by: Aurélien Lambert <aure@olli-ai.com>
aure-olli added a commit to aure-olli/helm that referenced this issue Sep 3, 2020
This is the 3rd and last PR splitted from helm#6876, and should be merged after helm#8677 and helm#8679

There have been many requests for a way to use templates for `values.yaml` (helm#2492, helm#2133, ...). The main reason being that it's currently impossible to derive the values of the subcharts from templates. However, having templates in `values.yaml` make them unparsable and create a "chicken or the egg" problem when rendering them.

This PR offers an intuitive solution without such a problem: an optional `values/` directory which templates are rendered using `values.yaml`, and then merge them with it. Those `values/` templates are only required for specific cases, work the same way as `templates/` templates, and `values.yaml` will remain the main parsable source of value.

Values evaluation is now made in 2 step. First the `values.yaml` file is read. Then the `values/***.yaml` files are rendered using those values (`values/_***.tpl` files ara still allowed as helpers), and are used to update the values.

For each chart and subchart, the following steps are performed:
1. If the chart has a parent, parent sub-values and global values are retrieved.
2. The chart values are coalesced with the retrieved value, the chart values are not authoritative.
3. The chart `values/` templates are rendered, the same way `templates/` templates are. The values are not updated during this step.
4. The values are updated with the rendered `values/` templates, sorted by name. The `values/` templates are authoritative and can replace values from the chart `values.yaml` or the previous `values/` templates.
5. The dependencies conditions and tags are evaluated over the updated values, and disabled dependencies are removed.
6. The same process is performed on enabled dependencies.

Once values are recursively updated, and once import values are treated on the enabled dependencies, those values are used for templates rendering.

Signed-off-by: Aurélien Lambert <aure@olli-ai.com>
@ramandeep-singh-1983
Copy link

I was facing the same issue i.e. passing a value set by user using --set to subchart. This came to my rescue:
helm install --set subchartname.subchartkey=myvalue

rm3l added a commit to Cosmo-Tech/cosmotech-api that referenced this issue May 21, 2021
However, this will not work since Argo installs
a Controller, and installing one per Release actually does not make
much sense We would actually end up with multiple Controllers and PostgreSQL pods,
which is actually useless.
Another issue is [1], which prevents from using the Helm release name to customize the sub-charts.

[1] helm/helm#2133
@bluebrown
Copy link

bluebrown commented Feb 15, 2022

See also #2514.

:) Thankfully, latest Helm manual says how to achieve this. https://helm.sh/docs/howto/charts_tips_and_tricks/#using-the-tpl-function

The trick is enclosing variable in " or in a yaml block |-, and than referencing it in a template as {{ tpl .Values.variable . }} This seems to make Helm happy.

Example:

$ cat Chart.yaml | grep appVersion
appVersion: 0.0.1-SNAPSHOT-d2e2f42


$ cat platform/shared/t/values.yaml | grep -A2 image:
image: 
  tag: |-
    {{ .Chart.AppVersion }}


$ cat templates/deployment.yaml | grep image:
          image: "{{ .Values.image.repository }}:{{ tpl .Values.image.tag . }}"


$ helm template . --values platform/shared/t/values.betradar.yaml | grep image
          image: "docker-registry.default.svc:5000/namespace/service:0.0.1-SNAPSHOT-d2e2f42"
          imagePullPolicy: Always
      image: busybox

Otherwise there is an error thrown..

$ cat platform/shared/t/values.yaml | grep -A1 image:
image: 
  tag: {{ .Chart.AppVersion }}

1 $ helm template . --values platform/shared/t/values.yaml | grep image
Error: failed to parse platform/shared/t/values.yaml: error converting YAML to JSON: yaml: invalid map key: map[interface {}]interface {}{".Chart.AppVersion":interface {}(nil)}

Can you do that with third party charts? I would assume this requires said third party to call tpl on the value you are using template syntax with, which is unlikely. If I am in control of the chart myself, I'd probably had a number of other fixes.

@TBBle
Copy link
Contributor

TBBle commented Feb 15, 2022

Yes, that depends on the third party chart to be calling tpl on various values it receives. I've noticed for example that the Bitnami charts are quite liberal in doing that, I guess partly because they are built using a lot of templates anyway.

So if you find a third-party chart that doesn't call tpl on a value you need it to call tpl on, perhaps open it with them as a feature request.

@lazychanger
Copy link

I submitted a plugin to override values.yaml with additional templates.

helm-viv
example

@edmondop
Copy link

This won't work however when you try to pass value down to children charts #2133 (comment)

@venkatesh3889
Copy link

any suggestion how we can handle "{{ .Values.images.abc-load-test }}" hyphen(-). it's failing.

@TBBle
Copy link
Contributor

TBBle commented Jul 5, 2023

You'll have to use something like {{ get $Values.images "abc-load-test" }}. If you get more complicated, e.g., the hyphenated-key is a dictionary too, you can use {{ $Values | dig "images" "abc-load-test" "subkey" }} to make things more readable than nested gets.

@venkatesh3889
Copy link

i am little confused here, can you give me some examples if possible? Thanks

@TBBle
Copy link
Contributor

TBBle commented Jul 6, 2023

I'd suggest opening a new ticket if you need further help, since this is a closed ticket and not actually related to your question. In that ticket, you can post more details of what you're trying to do, including an example of what isn't working, and you should be able to get more-detailed help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests