I am using Jenkins X and attempting to set different variables via values.yaml
files based upon the environment that I am promoting to. For example, when promoting a release from staging to production, I would like the values.yaml
file in my environment-xxxx-production
repository to override values in my project repository.
According to https://github.com/jenkins-x/jx/issues/1667#issuecomment-420901836 this comment, this should work simply by placing variables in the environment-xxxx-production
repository.
Sample deployment.yaml
file inside of my project.
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: {{ template "fullname" . }}
labels:
draft: {{ default "draft-app" .Values.draft }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
spec:
replicas: {{ .Values.replicaCount }}
template:
metadata:
labels:
draft: {{ default "draft-app" .Values.draft }}
app: {{ template "fullname" . }}
{{- if .Values.podAnnotations }}
annotations:
{{ toYaml .Values.podAnnotations | indent 8 }}
{{- end }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.internalPort }}
{{/*
Here's the section in question.
*/}}
{{- if .Values.env }}
env:
{{- if .Values.prBranch }}
- name: MY_ENV
value: "some_value"
{{- else }}
{{ toYaml .Values.env | indent 10 }}
{{- end }}
{{- end }}
livenessProbe:
httpGet:
path: {{ .Values.probePath }}
port: {{ .Values.service.internalPort }}
initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
successThreshold: {{ .Values.livenessProbe.successThreshold }}
timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
readinessProbe:
httpGet:
path: {{ .Values.probePath }}
port: {{ .Values.service.internalPort }}
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
successThreshold: {{ .Values.readinessProbe.successThreshold }}
timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
resources:
{{ toYaml .Values.resources | indent 12 }}
terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
Sample project values.yaml
contains this:
env:
- name: MY_ENV
value: "some_staging_value"
Sample environment-xxxx-production
values.yaml
contains this:
env:
- name: MY_ENV
value: some_production_value
I can certainly get the preview and staging environment variables working. However, when I promote the application to the production environment, the env
list in environment-xxxx-production
does not override the env
list in the values.yaml
file inside of the project itself.
the key in the production values.yaml
file needs to be the name of the chart you use in the requirements.yaml
- thats how helm does composed charts.
so if your app is called cheese
in requirements.yaml
try using this in the values.yaml
cheese:
env:
- name: MY_ENV
value: some_production_value
Worth noting that, as of today, the syntax seems to have changed.
When creating an app with jx create quickstart
, if we look at the deployment template (your-app/charts/your-app/templates/deployment.yaml
) it shows that the env section of the deployment is populated as follows:
env:
{{- range $pkey, $pval := .Values.env }}
- name: {{ $pkey }}
value: {{ quote $pval }}
{{- end }}
This means that in the values.yaml
file, present in your GitOps repos for staging, production and in your defaults in the app repo; your custom ENV variables should be added as:
your-app:
env:
MY_ENV_VAR: "Staging value for MY_ENV_VAR"
Where "your-app" is the name of your app, matching what is in requirements.yaml
, as James explained in his answer.