Transitioning to Helm

Shishir Khandelwal
4 min readNov 18, 2021

--

There are only a handful of teams that start their Kubernetes deployments with Helm in mind. Helm is usually an afterthought, something that engineers try to implement when the project gets bigger and requires better rollback strategies or a versioning approach.

The task of moving workloads to helm without any downtime is a challenge & requires planning. Though planning depends on use case and purpose, the method of moving — remains the same.

The steps required for moving to helm can be summarised as follows-

  1. Add helm labels & annotations to existing workloads.
  2. Save existing workloads as YAMLs.
  3. Create the Helm values file containing all the values such as image name, replica count, probe values, container arguments, env vars etc.
  4. Modify the YAMLs to use values from Helm values file.

I wrote about the first step (Add helm labels & annotations to existing workloads) in my previous article. You’ll find it here.

Link

In this article, the agenda is to see how steps 2,3 & 4 can be simplified & automated.

Let’s jump in.

Step 2 : Save existing workloads as YAML

Saving YAMLs of existing workloads is easy, the issue is that Kubernetes adds a lot of metadata to the workloads on its own.

Try the below sample command & see for yourself, you’ll notice a lot of data added which is not necessary from Helm's point of view. We must get rid of this extra data.

kubectl get deployment nginx -o json 
kubectl get deployment nginx -o yaml

We need clean YAMLs to proceed. How do we do that? JQ!

JQ is a tool that helps in manipulating JSON objects/files. We can use it to delete the unwanted components from the JSON output.

Let’s see how with an example.

  • Save the JSON output of the deployment as nginx.json
kubectl get deployment nginx -o json > nginx.json
  • Using JQ, remove the unwanted metadata & save the file as nginx-clean.json.
jq ‘del(.metadata.annotations[“deployment.kubernetes.io/revision”],.metadata.annotations[“kubectl.kubernetes.io/last-applied-configuration”],.metadata.creationTimestamp,.metadata.generation,.metadata.managedFields,.metadata.resourceVersion,.metadata.selfLink,.metadata.uid,.status)’ nginx.json >> nginx-clean.json

We now have YAMLs without the metadata. Let’s see the next step now.

Step 3: Create the Helm values file containing all the values such as image name, replica count, probe values, container arguments, env vars etc.

Though this step is usually done manually by copy pasting the values from the deployment yamls into the values.yaml file, I’ll be discussing an automated approach — as it can potentially save a lot of time.

Let’s see how.

  • JQ can be used to extract the required values. E.g. to extract the image name from a deployment yaml -
jq '.spec.template.spec.containers[0].image' nginx-clean.json
  • For other values such as env, hostAliases, probes etc — it is recommended to first extract & store the values in a separate JSON file & then use this file to create the values.yaml
jq '.spec.template.spec.containers[0].env' nginx-clean.json > nginx-clean-env.jsonjq '.spec.template.spec.containers[0].resources' nginx-clean.json > nginx-clean-resources.jsonjq '.spec.template.spec.containers[0].args' nginx-clean.json > nginx-clean-args.jsonjq '.spec.template.spec.hostAliases' nginx-clean.json > nginx-clean-hostAliases.json
  • The idea is to first have all the required values such as image name, replica count, probe values, container arguments, env vars and then combine them a single JSON file.
  • How do we combine all the separately extracted JSON values into a single JSON? JQ Again!
jq -n '{ nginx: { replicas: $replicas, env: $env, image: $image, resources: $resources, args: $args, hostAliases: $hostAliases} }' --argjson replicas $(jq '.spec.replicas' nginx-clean.json) --slurpfile env nginx-clean-env.json --argjson image $(jq '.spec.template.spec.containers[0].image' nginx-clean.json) --slurpfile resources nginx-clean-resources.json --slurpfile args nginx-clean-args.json --slurpfile hostAliases nginx-clean-hostAliases.json >> nginx_values.json

Read more about argjson & slurpfile arguments by running

jq --help
  • After the JSON file has been created, we need to simply convert the JSON file into YAML format as helm requires YAML files.
  • How do we convert a JSON file to it’s YAML equivalent? YQ!

YQ a lightweight and portable command-line YAML processor. yq uses jq like syntax but works with yaml files as well as json.

To convert a JSON file to YAML equivalent —

yq eval -P nginx_values.json > values.yaml

We now have a automated way to create the values.yaml file. By following this approach, we are saving efforts, reducing human errors & moving faster towards our goal.

Step 4: Modify the YAMLs to use values from Helm values file

This step is easy.

We need to replace the values in our nginx-clean.yaml file with helm placeholders. Some samples have been given below, they cover all the common cases.

For the resources section-

{{- toYaml (first .Values.nginx.resources) | nindent 12 }}

For the args section-

- args:
{{- toYaml (first .Values.nginx.args) | nindent 10 }}

For the env section-

env:
{{- toYaml (first .Values.nginx.env) | nindent 10 }}

For the image section-

image: {{ .Values.nginx.image }}

For the hostAliases section-

hostAliases:
{{- toYaml (first .Values.nginx.hostAliases) | nindent 6 }}

For the replicas section-

replicas: {{ .Values.nginx.replicas }}

For the rest, it’s easy to figure out by referring to the helm documentation.

That’s all folks. You can now transition your kubernetes deployment strategies to helm in a faster time and with less efforts!

Just one more thing, it would go a long way if you can leave a 👏🏻 clap 👏🏻 & follow me on medium — if you enjoyed this post & found it knowledgable. It encourages me to keep writing and helps other people in finding it :)

I share tips, experiences & articles on my Linkedin Account. You’ll love it if you are into Cloud, DevOps, Kubernetes etc. Following me over there — my LinkedIn account.

--

--

Shishir Khandelwal

I spend my day learning AWS, Kubernetes & Cloud Native tools. Nights on LinkedIn & Medium. Work: Engineering @ PayPal.