Multiline string inside a chart value - yaml

I am trying to create a helm chart. Inside the deployment folder I have a configmap template that looks like this:
apiVersion: v1
kind: ConfigMap
metadata:
name: config
data:
app-properties: |
{{ .Values.app.appProperties }}
My default values have this:
app:
appProperties: |
line1
That code appears to work, but I need more lines in app.appProperties and the moment I add more lines there like this:
app:
appProperties: |
line1
line2
line3
I get:
upgrade.go:142: [debug] preparing upgrade for myhelm
Error: UPGRADE FAILED: YAML parse error on helm/templates/cms.yml: error converting YAML to JSON: yaml: line 11: could not find expected ':'
helm.go:84: [debug] error converting YAML to JSON: yaml: line 11: could not find expected ':'
YAML parse error on helm/templates/cms.yml
The templated definition I was expecting should be:
apiVersion: v1
kind: ConfigMap
metadata:
name: config
data:
app-properties: |
line1
line2
line3
What's the right way to do that ?

The reason here is mostly because of the incorrect indentation which you can verify by running helm template with --debug flag. You could either use only nindent 4 with your values as that seems to be the correct indentation level or also use tpl if the multiline string has some templates inside which you want to move in the config map.
{{- /*
ConfigMap template
*/ -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: config
data:
app-properties:
{{- .Values.app.appProperties | nindent 4 }}
---
## Values File
app:
appProperties: |
line1
line2
line3
Result
➜ $ helm template ./
---
# Source: my-local-functions/templates/multi-line-string.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: config
data:
app-properties:
line1
line2
line3
Example with tpl function
{{- /*
In the templates directory somefile.yaml
*/ -}}
multiLineString:
{{- tpl .Values.multiLine . | nindent 2 }}
---
## Values Files
extraFruits: banana
multiLine: |
I am a line
{{ .Values.extraFruits }}
Result:
➜ $ helm template ./
---
# Source: my-local-functions/templates/somefile.yaml
multiLineString:
I am a line
banana
Hope this helps.

Related

Helm Chart Error when using functions: " invalid value; expected string"

I defined the following ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: test-application-yaml
data:
application.yaml: |-
testOne: {{ .Values.testOne | nindent 6 }}
testTwo: {{ .Values.testTwo | nindent 6 }}
The values.yaml looks as follows:
test:
replicas: 1
testOne: |
testOne: "test1"
testTwo: "test2"
testTwo: |
testThree: "test3"
testFour: "test4"
When executing helm lint -f $v helm/charts/applications on Azure, the following error message is reported:
[ERROR] ... at <6>: invalid value; expected string
When trying it on my machine via helm template -f .\values.yaml . however, i get the configMap correctly indented:
apiVersion: v1
kind: ConfigMap
metadata:
name: test-application-yaml
data:
application.yaml: |-
testOne:
testOne: "test1"
testTwo: "test2"
testTwo:
testThree: "test3"
testFour: "test4"
What am I missing here?

Helm iterate over string with comma separated values

I'd like to iterate over string which contain comma separated values using range. For example:
DNS_NAMES: example.com, example2.com, example3.com
and then iterate using range over values: example.com, example2.com, example3.com
use split
values.yaml
DNS_NAMES: example.com, example2.com, example3.com
templates/cm.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: test
data:
config.yaml: |-
args:
{{- range ( split ", " $.Values.DNS_NAMES ) }}
- {{ . }}
{{- end }}
output.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: test
data:
config.yaml: |-
args:
- example.com
- example2.com
- example3.com

Ansible Jinja2 template - Remove trailing whitespace

I am trying to load an ansible vault file into an k8 configmap YAML file using Ansible Jinja template but facing an issue with a trailing whitespace getting added at the end of the contents of the YAML file. This is causing errors as below:
Vault format unhexlify error: Odd-length string
Sample of ansible template am using is :
Playbook main.yml -
- name: display multiple files
shell: cat /tmp/test.yml
register: test
Ansible Jinja Template
apiVersion: v1
data:
test.yml: |-
{{ test.stdout.splitlines()|indent(4, false)|trim|replace(' ','') }}
kind: ConfigMap
metadata:
name: test
namespace: test-namespace
test.yml example:
$ANSIBLE_VAULT;1.1;AES256
62313365396662343061393464336163383764373764613633653634306231386433626436623361
6134333665353966363534333632666535333761666131620a663537646436643839616531643561
63396265333966386166373632626539326166353965363262633030333630313338646335303630
3438626666666137650a353638643435666633633964366338633066623234616432373231333331
6564
Output YAML created from Jinja Template is below
apiVersion: v1
data:
test.yml:
$ANSIBLE_VAULT;1.1;AES256
62313365396662343061393464336163383764373764613633653634306231386433626436623361
6134333665353966363534333632666535333761666131620a663537646436643839616531643561
63396265333966386166373632626539326166353965363262633030333630313338646335303630
3438626666666137650a353638643435666633633964366338633066623234616432373231333331
6564
kind: ConfigMap
metadata:
name: test
namespace: test-namespace
Can you please let me know what i may be missing in my ansible template file to fix the above trailing whitespace issues.
I am trying to load a Ansible Vault encrypted file into a configmap using jinja2 templating
Then you are solving the wrong problem; let the to_yaml filter do all that escaping for you, rather than trying to jinja your way through it.
- command: cat /tmp/test.yml
register: tmp_test
- set_fact:
cm_skeleton:
apiVersion: v1
data:
kind: ConfigMap
metadata:
name: test
namespace: test-namespace
- copy:
content: >-
{{ cm_skeleton | combine({"data":{"test.yml": tmp_test.stdout}}) | to_yaml }}
dest: /tmp/test.configmap.yml
If you have other things you are trying to template into that ConfigMap, fine, you can still do so, but deserialize in into a dict so you can insert the literal contents of test.yml into the dict and then re-serialize using the to_yaml filter:
- set_fact:
cm_skeleton: '{{ lookup("template", "cm.j2") | from_yaml }}'
- copy:
contents: '{{ cm_sketeton | combine({"data"...}) | to_yaml }}'

Is it possible to use a template inside a template with go template

Using https://golang.org/pkg/text/template/, I sometimes need to use variables in the accessed path (for kubernetes deployments).
I end up writing something like :
{{ if (eq .Values.cluster "aws" }}{{ .Values.redis.aws.masterHost | quote }}{{else}}{{ .Values.redis.gcp.masterHost | quote }}{{end}}
What I'd really like to write is pretty much {{ .Values.redis.{{.Values.cluster}}.masterHost | quote }} , which doesn't compile.
Is there a way to write something similar ? (so having a kind of variable in the accessed path).
You can use _helpers.tpl file to define logic and operate with values.
_helpers.tpl
{{/*
Get redis host based on cluster.
*/}}
{{- define "chart.getRedis" -}}
{{- if eq .Values.cluster "aws" -}}
{{- .Values.redis.aws.masterHost | quote -}}
{{- else -}}
{{- .Values.redis.gcp.masterHost | quote -}}
{{- end -}}
{{- end -}}
values.yaml
cluster: local
redis:
aws:
masterHost: "my-aws-host"
gcp:
masterHost: "my-gcp-host"
And use it in your Deployment (here's a ConfigMap example to keep it shorter)
configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: Configmap
data:
redis: {{ template "chart.getRedis" . }}
Output:
helm install --dry-run --debug mychart
[debug] Created tunnel using local port: '64712'
...
COMPUTED VALUES:
cluster: local
redis:
aws:
masterHost: my-aws-host
gcp:
masterHost: my-gcp-host
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: Configmap
data:
redis: "my-gcp-host"
Set cluster value to aws:
helm install --dry-run --debug mychart --set-string=cluster=aws
[debug] Created tunnel using local port: '64712'
...
COMPUTED VALUES:
cluster: local
redis:
aws:
masterHost: my-aws-host
gcp:
masterHost: my-gcp-host
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: Configmap
data:
redis: "my-aws-host"

Helm yaml keys from values.yaml

I want to make a yaml KEY (not the value) dynamically.
In my values.yaml
failoverip1: 0.0.0.0` (<- this is only a demo IP)
In my templates/configmap.yaml I have this:
apiVersion: v1
kind: ConfigMap
metadata:
name: vip-configmap
data:
{{- .Values.failoverip1 -}}: {{ .Release.Namespace -}}/{{- .Values.target -}}
^^^^^^^^^^^^^^^^^^^^^----> here should be an IP address from values.yaml
{{ .Release.Namespace -}}/{{- .Values.target -}} renders successfully.
But if I add {{- .Values.failoverip1 -}} to the key part, it renders nothing.
(Nothing means, the whole data: block, does not get rendered.
This is the error message when I run helm install --name hetzner-failover .
Error: YAML parse error on hetzner-failover/templates/configmap-ip.yaml: error converting YAML to JSON: yaml: line 4: mapping values are not allowed in this context
Is it not allowed to make a
key dynamic?
If not, how to drive around that?
Here is the repo I am talking of:
https://github.com/exocode/helm-charts/blob/master/hetzner-failover/templates/configmap-ip.yaml
The error seems to be, that the leading - got cut.
So the correct way is to remove that minus:
Before:
{{- .Values.failoverip1 | indent 2 -}}
After:
{{ .Values.failoverip1 | indent 2 -}}
The yaml is now:
apiVersion: v1
kind: ConfigMap
metadata:
name: vip-configmap
data:
{{ .Values.failoverip1 | indent 2 -}}: {{ .Release.Namespace -}}/{{- .Values.target -}} # add your config map here. must map the base64 encoded IP in secrets.yaml
And the rendered result is:
kubectl get configmap -o yaml
apiVersion: v1
items:
- apiVersion: v1
data:
0.0.0.0: default/nginx# add your config map here. must map the base64 encoded
IP in secrets.yaml
kind: ConfigMap

Resources