Search code examples
kubernetesyamlopenshiftkubernetes-helm

helm template not working with tls string formatted key


I am working on helm template with some tls certificate, I am not able to create proper formatted .yml file

Details as below,

Values.yml is different for each environment so key string also change, so I am loading that certificate at runtime.

values.yml

SERVER_KEY: '-----BEGIN CERTIFICATE-----\nsadasdasdadasdadad\nasdsadsadasdsad\n-----END CERTIFICATE-----'

I am using above SERVER_KEY in Route.yml to load key like key: {{ .Values.SERVER_KEY }}

Route.yml

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  labels:
    type: sharded
  name: hello-openshift-edge
  namespace: hello-openshift
spec:
  subdomain: hello-openshift
  tls:
    termination: edge
    key: {{ .Values.SERVER_KEY }}
  to:
    kind: Service
    name: hello-openshift

I am expecting my yml like below after load my certificate in key,

expected output Route.yml

.
.
spec:
  subdomain: hello-openshift
  tls:
    termination: edge
    key: |
      -----BEGIN CERTIFICATE-----
      nsadasdasdadasdadad
      nasdsadsadasdsad
      -----END CERTIFICATE-----

In one of the place I have done using below,

key: !Sub "${SERVER_KEY}"

But in case of helm template it is not working for me.

Can someone please tell me how to convert that sting in proper format.

Thanks Bhushan


Solution

  • Helm on its own doesn't deal with many significant points of YAML formatting. Your template code on its own is responsible for quoting or otherwise escaping complex string content. Simply using {{ .Values.something }} will work for values that don't contain newlines or punctuation, but otherwise you need more escaping.

    The YAML block scalar syntax you show in the expected output is fine, but you need to generate it yourself.

    spec:
      tls:
        key: |
    {{ .Values.SERVER_KEY | indent 6 }}
    

    (Note that the last line is not indented. indent adds leading whitespace at the start of the first line.)

    Helm also contains toJson and toYaml extension functions. Valid JSON is also valid YAML, so you can encode an arbitrary value via toJson, and this will have clearer behavior if you expect the value to be a multi-line string (newlines will be escaped). So this will also work:

    spec:
      tls:
        key: {{ toJson .Values.SERVER_KEY }}
    

    Both of these assume the SERVER_KEY value is an ordinary string with embedded newlines. In your sample values file, you use a YAML single-quoted string, but (like in the Unix Bourne shell) this preserves \n escape sequences as two characters "backslash", "n". You either need a double-quoted string

    SERVER_KEY: "-----BEGIN CERTIFICATE-----\n..."
    

    or a block scalar

    SERVER_KEY: |
      -----BEGIN CERTIFICATE-----
      ...
    

    Both forms are standard YAML and Helm will consume both of them to form a string with embedded newlines, as you expect.