carvel-dev / ytt

YAML templating tool that works on YAML structure instead of text
https://carvel.dev/ytt
Apache License 2.0
1.68k stars 137 forks source link

Variable in `ConfigMap` was not rendered #769

Closed astraw99 closed 1 year ago

astraw99 commented 1 year ago

What steps did you take: A configmap yaml was configed like this: configmap.yaml

#@ load("@ytt:data", "data")
apiVersion: v1
data:
  config.yaml: |
    cluster: #@ data.values.cluster.config
kind: ConfigMap
metadata:
  name: my-cm
  namespace: default

data.yaml

cluster:
  config: val

Then do ytt -f ./configmap.yaml --data-values-file ./data.yaml > ytt-demo.yaml, just got:

apiVersion: v1
data:
  config.yaml: |
    cluster: #@ data.values.cluster.config
kind: ConfigMap
metadata:
  name: my-cm
  namespace: default

What happened: See above.

What did you expect: Variable in all K8s resources should be rendered consistently.

Anything else you would like to add: [Additional information that will assist in solving the issue.]

Environment:

mamachanko commented 1 year ago

Thank you for asking this @astraw99 !

The issue here is that the value of config.yaml entry is a string. To ytt its not a template, but just a string.

There are two approaches here; a discouraged and a recommended one. I will show you both.

[discouraged] text templating

First, you can use ytt's [text templating]() to render a string with variables.

I created a gist for your example. Try it on the playground.

#@ load("@ytt:data", "data")
apiVersion: v1
data:
  #@yaml/text-templated-strings
  config.yaml: |
    cluster: (@= data.values.cluster.config @)
kind: ConfigMap
metadata:
  name: my-cm
  namespace: default

This works, but you are now responsible for rendering valid YAML.

[recommended] encode as YAML

The better approach here is to create a map which represents your config.yaml and encode it as YAML.

I created a gist for your example. Try it on the playground.

#@ load("@ytt:data", "data")
#@ load("@ytt:yaml", "yaml")

#@ def config():
cluster: #@ data.values.cluster.config
#@ end

---
apiVersion: v1
data:
  config.yaml: #@ yaml.encode(config())
kind: ConfigMap
metadata:
  name: my-cm
  namespace: default

Now, you don't need to worry about rendering a valid YAML string. The yaml module takes care of that.

pivotaljohn commented 1 year ago

@astraw99 if you have more you'd like support, here... please reply to this issue and we'll reopen. Otherwise, we assume this has been answered (thanks again @mamachanko!)