How to set the "required" value in templates from --set option? - kubernetes

How to force to specify --set option on helm install|upgrade?
in my case, some required environment variables. (e.g. "database.password")
Files
.
|-- Chart.yaml
|-- templates
| |-- NOTES.txt
| |-- _helpers.tpl
| |-- deployment.yaml
| |-- ingress.yaml
| |-- secret.yaml
| `-- service.yaml
`-- values.yaml
values.yaml (snip)
#...
database:
useExternal: no
host: "pgsql"
port: "5432"
name: "myapp"
userName: "myapp_user"
# password shouldn't write here.
# I want to be inject this value to secret.
password: ""
#...
templates/secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: myapp-secrets
type: Opaque
data:
app-database-password: {{required .Values.database.password | b64enc | quote }}
templates/deployment.yaml (snip)
#...
env:
- name: APP_DATABASE_HOST
value: {{ .Values.database.host | quote }}
- name: APP_DATABASE_PORT
value: {{ .Values.database.port | quote }}
- name: APP_DATABASE_NAME
value: {{ .Values.database.name | quote }}
- name: APP_DATABASE_USERNAME
value: {{ .Values.database.username | quote }}
- name: APP_DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: myapp-secrets
key: app-database-password
#...
command
# Retrieve from GCP KMS(prod) or define directly(dev)
DATABASE_PASSWORD=$( ... )
# Deploy.
helm upgrade --install \
-f ./values.yaml \
--set database.password=$DATABASE_PASSWORD \
myapp-dev ./ --dry-run --debug
It's failed with error.
Error: render error in "myapp/templates/secret.yaml": template: myapp/templates/secret.yaml:7:28: executing "myapp/templates/secret.yaml" at <required>: wrong number of args for required: want 2 got 1
It seems the required function is evaluate template file statically when parsing.
I need matters below:
database.password is switchable by env such as "prod" or "stage".
database.password should store to secret.
I want to set the actual database.password value using env vars on command execution.
Any ideas?

The Helm-specific required macro takes two parameters: the error message if the value isn't present, and the value that you're checking for. This syntax also lets it be used in pipeline form. In your example, the secret value could be
app-database-password: {{.Values.database.password | required "database password is required" | b64enc | quote }}

Related

Helm not using values override?

I'm using sub-charts. Here's my directory structure
/path/microservice-base-chart
/path/myApp
I have this values.yaml for my "base" (generic) chart
# Default region and repository
aws_region: us-east-1
repository: 012234567890.dkr.ecr.us-east-1.amazonaws.com
repositories:
us-east-1: 01234567890.dkr.ecr.us-east-1.amazonaws.com
eu-north-1: 98765432109.dkr.ecr.eu-north-1.amazonaws.com
image:
name: ""
version: ""
...and this in the base chart's templates/_helpers.yaml file
{{/*
Get the repository from the AWS region
*/}}
{{- define "microservice-base-chart.reponame" -}}
{{- $repo := index .Values.repositories .Values.aws_region | default .Values.repository }}
{{- printf "%s" $repo }}
{{- end }}
...and this in the base chart's templates/deployment.yaml file
apiVersion: apps/v1
kind: Deployment
...
spec:
...
template:
...
spec:
...
containers:
- name: {{ .Values.image.name }}
image: {{ include "microservice-base-chart.reponame" . }}/{{ .Values.image.name }}:{{ .Values.image.version }}
I have this in the Chart.yaml of a sub chart that uses the base chart.
dependencies:
- alias: microservice-0
name: microservice-base-chart
version: "0.1.0"
repository: file://../microservice-base-chart
...and this in the values.yaml of a sub chart
microservice-0:
image:
name: myApp
version: 1.2.3
However, when I run this, where I set aws_region
$ helm install marcom-stats-svc microservice-chart/ \
--set image.aws_region=eu-north-1 \
--set microservice-0.image.version=2.0.0 \
--dry-run --debug
I get this for the image name of the above deployment.yaml template
image: 01234567890.dkr.ecr.us-east-1.amazonaws.com/myApp:2.0.0
instead of the expected
image: 98765432109.dkr.ecr.eu-north-1.amazonaws.com/myApp:2.0.0
What am I missing? TIA

Replacing variables in external file through playbook

I would like to use variables (vars.yaml) to replace the content in a config file (config.yaml) and automatise the process in the playbook (playbook.yaml). But I can't found a type of process that automaticly search for vars inside an external file through the playbook.yaml.
My files look like this :
vars.yaml
---
var1: content1
var2: content2
var3: content3
config.yaml:
apiVersion: 1
datasources:
- name: {{ var1 }}
type: {{ var2 }}
access: proxy
url: {{ var3 }}
playbook.yaml:
---
- name: Deploy
hosts: localhost
tasks:
- include_vars: ./vars.yaml
- name: Update config file
# Something to replace all vars in the config file using the content of vars.yaml
Can you help me and tell me if there is something possible instead of doing a regex for each variable ...?
The file with the unresolved variables is actually a template. Let's name it this way
shell> cat config.yaml.j2
apiVersion: 1
datasources:
- name: {{ var1 }}
type: {{ var2 }}
access: proxy
url: {{ var3 }}
Use the template module to update config.yaml, e.g.
- include_vars: vars.yaml
- name: Update config file
template:
src: config.yaml.j2
dest: config.yaml
gives
shell> cat config.yaml
apiVersion: 1
datasources:
- name: content1
type: content2
access: proxy
url: content3

How to use environment/secret variable in Helm?

In my helm chart, I have a few files that need credentials to be inputted
For example
<Resource
name="jdbc/test"
auth="Container"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://{{ .Values.DB.host }}:{{ .Values.DB.port }};selectMethod=direct;DatabaseName={{ .Values.DB.name }};User={{ Values.DB.username }};Password={{ .Values.DB.password }}"
/>
I created a secret
Name: databaseinfo
Data:
username
password
I then create environment variables to retrieve those secrets in my deployment.yaml:
env:
- name: DBPassword
valueFrom:
secretKeyRef:
key: password
name: databaseinfo
- name: DBUser
valueFrom:
secretKeyRef:
key: username
name: databaseinfo
In my values.yaml or this other file, I need to be able to reference to this secret/environment variable. I tried the following but it does not work:
values.yaml
DB:
username: $env.DBUser
password: $env.DBPassword
you can't pass variables from any template to values.yaml with helm. Just from values.yaml to the templates.
The answer you are seeking was posted by mehowthe :
deployment.yaml =
env:
{{- range .Values.env }}
- name: {{ .name }}
value: {{ .value }}
{{- end }}
values.yaml =
env:
- name: "DBUser"
value: ""
- name: "DBPassword"
value: ""
then
helm install chart_name --name release_name --set env.DBUser="FOO" --set env.DBPassword="BAR"

How to write below condition in Helm chart syntax in a job.yaml file?

I have to write this condition in helm chart syntax in job.yaml file so that imagePullSecrets get's executed only when the condition is satisfied.
Condition is
when: (network.docker.username | default('', true) | trim != '') and (network.docker.password | default('', true) | trim != '')
To write above condition below this code:
imagePullSecrets:
- name: "{{ $.Values.image.pullSecret }}"
Ideally, Docker username & password should come from Secrets. Here's the Sample helm code to use if in yaml file:
imagePullSecrets:
{{ if and (ne $.Values.network.docker.password '') (ne $.Values.network.docker.username '') }}
- name: "{{ $.Values.image.pullSecret }}"
{{ end }}
And values.yaml should have:
network:
docker:
username: your-uname
password: your-pwd

Helm integer intended to be string value parsed with escape character "\u200"

I have this Secret resource yaml:
...
stringData:
imageTag: {{ .Values.image.tag | quote }}
...
In the value file:
image:
tag: "65977​45"
...
When running the helm template command results to a generated yaml file with the value:
...
stringData:
imageTag: "65977\u200b45"
...
Seems like a bug in helm. To get around this issue, I have to do this:
...
stringData:
imageTag: "{{ .Values.image.Tag }}"
...
Is there a better solution? I am using helm version 2.15.2