I am trying to access a file inside my helm templates as a config map, like below. I get an error as below.
However, it works when my application.yml doesn't have nested objects (Eg - name: test). Any ideas on what I could be doing wrong?
config-map.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
{{.Files.Get “application.yml”}}
application.yml:
some-config:
application:
name: some-application-name
ERROR:
*ConfigMap in version “v1" cannot be handled as a ConfigMap: v1.ConfigMap.Data: ReadString: expects ” or n, but found {, error found in #10 byte of ...|ication”*
Looks like you have an indentation issue on your application.yaml file. Perhaps invalid YAML? If I try your very same files I get the following:
○ → helm template ./mychart -x templates/configmap.yaml
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: release-name-configmap
data:
some-config:
application:
name: some-application-name
As per documentation:
Templates should be indented using two spaces (never tabs).
Template directives should have whitespace after the opening braces and before the closing braces.
finally it should looks like:
{{ .Files.Get "application.yml" | nindent 2 }}
or
{{- .Files.Get "application.yml" | nindent 2 }}
to chomp whitespace on the left
Related
I have created a secret.yaml file as follows:
apiVersion: v1
kind: Secret
metadata:
name: my-secret
data:
truststore.jks: {{ (.Files.Glob "../trust.jks").AsSecrets | b64enc }}
I am calling this as part of template .yaml file in HELM.
.yaml
apiVersion: v1
kind: DeploymentConfig
spec:
...
template:
spec:
...
container:
- name: "my-container"
...
volumeMounts:
- name: secrets
mountPath: /mnt/secrets
readOnly: true
volumes:
- name: secrets
secret:
secretName: "my-secret"
When I run helm install command the pod gets created successfully, and the volume is also mounted, but if I check the truststore.jks in /mnt/secrets using cat command below is the output:
cat /mnt/secrets/truststore.jks
{}
I ran the dry run command to check the generated .yaml file, the secret is populted as below:
# Source: ag-saas/templates/tsSecret.yaml
apiVersion: v1
kind: Secret
metadata:
name: my-secret
data:
truststore.jks: e30=
How do I get the file into my secret?
There's a couple of things going on here:
.Files.Glob is intended to retrieve multiple files, e.g. .Files.Glob "credentials/*.jks". For a single file .File.Get will retrieve its contents directly.
You can only access files inside the chart directory; referencing .Files.Get "../trust.jks" won't work.
.Files.Glob.AsSecret renders a list of files to the entire contents of the data: block; you just directly need the file content.
So your Secret should look like
apiVersion: v1
kind: Secret
metadata:
name: my-secret
data:
truststore.jks: {{ .Files.Get "trust.jks" | b64enc }}
where in the last line I've used .Files.Get, I've not tried to refer to a "../..." path outside the chart, and I don't render it to ...AsSecret.
You also will need to move or copy (not symlink) the keyset file into the chart directory for this to work.
(In the current form, .Files.Glob won't match anything outside the chart directory, so you get an empty list of files. Then rendering that to .AsSecrets gets you an empty JSON object. You're using that string {} as the secret value, which gets correctly base64-encoded, but that's why {} comes out at the end.)
Im trying to format my yml to be more readable.
I have an if statement that is really long with a bunch of and/ors and I would like to be able to spread it across multiple lines
So something along the lines of
{{-if or
(eq 'abc' .values.foo)
(eq 'def' . values.bar)
}}
Def:'works'
{{- end}}
But this throws up errors for incomplete if statement.
Is there some special character or syntax I can use to achieve the above?
helm supports direct line breaks without special characters.
Missing a space between {{ and if.
There is an extra space between . and values.
String constants require double quotes.
demo:
values.yaml
foo: xxx
bar: yyy
templates/cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: test
labels:
{{- include "test.labels" . | nindent 4 }}
data:
cfg: |-
{{- if or
(eq "abc" .Values.foo)
(eq "def" .Values.bar)
}}
if
{{- else }}
else
{{- end }}
cmd
helm template --debug test .
output
apiVersion: v1
kind: ConfigMap
metadata:
name: test
data:
cfg: |-
else
I'm quite new for kubernetes. I am trying to create configmap with using yaml file which was user defined.
helm upgrade --install test --namespace test --create-namespace . -f xxx/user-defined.yaml
user can add any yaml file with using 'f' option.
for example;
cars.yaml
cars:
- name: Mercedes
model: E350
So command will be;
helm upgrade --install test --namespace test --create-namespace . -f xxx/cars.yaml
My question is, I want to create configmap which is name 'mercedes-configmap'
I need to read that values from cars.yaml and create automaticaly configmap with name and data of cars.yaml
Update,
I've created below configmap template;
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.cars.name }}-configmap
data:
{{- range .Files }}
{{ .Files.Get . | toYaml | quote }}
{{- end }}
The only issue that I faced, I couldnt get the whole file data.
Welcome to the community!
I have created a helm template for configmap. It works this way: you can pass configmap name - name and file name - fname where data is stored and/or it can read files from a specific folder.
Please find the template (first 3 lines are commented, it's two working implementations of logic to check values existing):
{{/*
{{ if not (or (empty .Values.name) (empty .Values.fname)) }}
*/}}
{{ if and (not (empty .Values.name)) (not (empty .Values.fname)) }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.name }}-configmap
data:
{{- ( .Files.Glob .Values.fname ).AsConfig | nindent 2 }}
---
{{ end }}
{{ $currentScope := .}}
{{ range $path, $_ := .Files.Glob "userfiles/*.yaml" }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ base $path | trimSuffix ".yaml" }}-configmap
data:
{{- with $currentScope}}
{{ base $path }}: |
{{- ( .Files.Get $path ) | nindent 4 }}
{{- end }}
---
{{ end }}
First part of the template checks if configmap name and file name are set and if so, it renders it. Second part goes to userfiles directory and gets all yamls within.
You find github repo where I shared file examples and configmap.
To render the template with cars2.yaml and with/without files within userfiles directory:
helm template . --set name=cars2 --set fname=cars2.yaml
To render the same template with only files in userfiles directory:
helm template .
P.S. helm v3.5.4 was used
Useful links:
Accessing files in helm
Flow control
File path functions
I have a helm chart that is creating a config map for which I am passing content as a value from terraform using helm_release.
values.yml: default is empty
sql_queries_file: ""
helm template for configmap:
apiVersion: v1
kind: ConfigMap
metadata:
name: sql-queries
data:
{{ .Values.sql_queries_file }}
terraform file:
resource "helm_release" "example" {
............
..................
set {
name = "sql_queries_file"
value = file(./sql_queries.sql)
}
}
I have a sql_queris.sql fine inside terraform folder with sample data below.
-- From http://docs.confluent.io/current/ksql/docs/tutorials/basics-docker.html#create-a-stream-and-table
-- Create a stream pageviews_original from the Kafka topic pageviews, specifying the value_format of DELIMITED
CREATE STREAM pageviews_original (viewtime bigint, userid varchar, pageid varchar) WITH (kafka_topic='pageviews', value_format='DELIMITED');
Error:
Failed parsing key sql_queries_file with value <entire content here>
Is this the right way? or is there a better way?
I would use filebase64 to get the file with terraform to avoid templating issues. You can unmarshal it in helm like this: {{ b64dec .Values.sql_queries_file }}. By the way you should use data field in configMaps like this:
apiVersion: v1
kind: ConfigMap
metadata:
name: sql-queries
data:
sql_queries.sql: |-
{{ .Values.sql_queries_file | nindent 4 }}
# {{ b64dec .Values.sql_queries_file | nindent 4 }} if you want to unmarshal
Edit: fixed typo in answer.
I have the following files
mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.env.{{lle.dev}} }}-configmap
data:
myvalue: "Hello World"
mychart/values.yaml
env:
lle.dev: ABC
lle.qa: CDE
How do I access the values in the helm template? nested curly braces are also not allowed. Also the below didn't work
name: {{ .Values.env.lle.dev }}-configmap
Reason being it is considering lle, dev as a separate sub keys for env and not as a single key.
Is there a reason you are trying to prefix your variables with lle? If not, you can rewrite your values.yaml file in the following way:
env:
lle:
dev: ABC
qa: CDE
Then you will be able to access your variables as in name: {{ .Values.env.lle.dev }}-configmap