0

I am trying to create a blue/green deployment Helm chart, but struggling with how to switch the primary/secondary and have the labels move with the deployments.

Effectively, I setup the Helm chart using 2 "slots" defined in the values.yaml file:

blue:
  enabled: false

green:
  enabled: false

productionSlot: blue

image:
  name: "nginx"
  blue_tag: "latest"
  green_tag: "latest"
...

Then in my deploy.yaml and service.yaml I switch on/off the template like this:

{{- if .Values.blue.enabled }}
  {{- $_ := set . "currSlot" "blue" }}
  {{- template "blue-green-deploy.deployment" . }}
{{- end }}
{{- if .Values.green.enabled }}
{{- if .Values.blue.enabled }}
---
{{- end }}
  {{- $_ := set . "currSlot" "green" }}
  {{- template "blue-green-deploy.deployment" . }}
{{- end }}

And then the Deployment looks something like:

{{- define "blue-green-deploy.deployment" -}}
{{- $currSlot := (pluck .currSlot .Values | first) }}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "blue-green-deploy.fullname" . }}-{{ .currSlot }}
  labels:
    release: {{ .Release.Name }}
    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    app: {{ template "blue-green-deploy.name" . }}
    version: {{ $currSlot.appVersion | quote }}
    slot: {{ .currSlot }}
    route: {{ template "blue-green-deploy.route" . }}
...

Effectively I call the same template, but with the currSlot set to the proper slot I am processing. On the first deploy I set both blue and green to "enabled". After that, whichever is not the primary I set it to "enabled" w/ the new version, do the deploy (which updated just the deployment and the service, not the Istio resources)

Then, once integration testing completes on the new pods, if successful I "flip" the productionSlot value and the alt becomes the primary and the primary becomes the alt by swapping the Istio DestinationRules subset filters.

...
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: {{ include "blue-green-deploy.fullname" . }}-dr
spec:
  host: {{ include "blue-green-deploy.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
  subsets:
  - name: primary
    labels:
      slot: {{ .Values.productionSlot }}
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: {{ include "blue-green-deploy.fullname" . }}-dr-alt
spec:
  host: {{ include "blue-green-deploy.fullname" . }}-{{ if eq .Values.productionSlot "blue" }}green{{ else }}blue{{ end }}.{{ .Release.Namespace }}.svc.cluster.local
  subsets:
  - name: alt
    labels:
      slot: {{ if eq .Values.productionSlot "blue" }}green{{ else }}blue{{ end }}

To "swap" the blue/green routes, I simply call helm passing in the productionSlot value like this:

helm upgrade test-app . --namespace test --install --set productionSlot=green --reuse-values --wait

Where I am struggling is I need to update the route label of the Deployments themselves as well, but when I do the route switch I am not setting either blue or green "enabled" as I don't want to override their deployed pods at all...I just need to update the label on the Deployment, and by extension the Pods.

Is there a way to do that with Helm? If I set the blue.enabled and/or green.enabled to true then it's going to force the deployment change and reinstall the pods, right?

CodeChimp
  • 8,016
  • 5
  • 41
  • 79
  • I did confirm, running the "swich" command w/ blue.enabled=true and green.enabled=true DOES update the labels correctly, but it also does a restart of the pods. – CodeChimp Dec 27 '22 at 19:00
  • Can you do this with a chart that deploys the application just once; then `helm install` it twice to have two releases named "blue" and "green"; then manage the DestinationRule or other routing separately? What change do you need to make to `route`? You do need to set one or the other of the `enabled` flags, but `helm upgrade --reuse-values` does that already. – David Maze Dec 28 '22 at 12:58
  • @DavidMaze If I understand your comment correctly, the issue isn't in helm remembering the previous value. The issue is when I update a label, it also does a deploy. What I am attempting to do is update the label without a deploy happening. I am trying to keep the label in-sync with which set of pods are the "active" pods so when people need to see which pods are active they can just simply check the label. – CodeChimp Jan 04 '23 at 19:55
  • What does "do a deploy" mean here? If you run `helm upgrade` it will always render the entire chart, compare it to some previous state, and ask the cluster to make the required changes. If you are changing the `slot` label on the pod template in a Deployment spec, that will cause the current Pods to get rotated out. – David Maze Jan 05 '23 at 01:51

0 Answers0