Creating a Helm Chart

7 min readApr 16, 2020


One more step in our automation quest…

In my last post, I covered GitOps, how we got here, and why it’s important. In this post, we are going to get back to the technical stuff and cover the deployable artifact, a Helm Chart.

Where we are in our stages

As a quick recap, by going #GitOps, I’ve decided my entire stack will now be configured in Git. From the host configuration to the latest version of my microservices, it’s all in there.

In this post, I will be converting the Airwave Tech hello-word service into a helm chart. Once the chart is set up, our next post will cover the automated deployment of the chart into our minikube cluster.

A couple of rules first

  • chart names should be lower case letters, numbers and dashes. No underscores, dots, or uppercase letters. Stay away from special characters too, like /\!@#$%^ and others.
  • Chart names must match the name of the parent directory. If you have a chart named myapp, it should be in a directory called myapp. This will get made automatically as you will see below.
  • Helm uses SemVer2 verisoning.
  • have Helm installed on your machine

Hello-World, again.

Here’s our repo. It has all the completed files in it.

We are using Helm v.3.1.2.

Initialize your directory

Navigate to the root of your source code and run this command helm create <chart-name> . This will create a new sub-directory with the name of your chart. In our case it’s hello-world.

newly created directory structure

Delete the contents of the following files, but don’t delete the files themselves.


This is because when you create a chart, it creates NGINX by default.

empty files



This defines the metadata of your chart. You can supply values for the name of your chart, the version, etc.


As you can see, all you have to do is replace the default values with your own, which I have done so already. The included comments are super helpful in understanding what you need to change.



Values are just what you think they are. They are key:value pairs that are passed to Chart templates at install time. This will make sense in a just a moment.

When you open this file, you will see some data in there. Select all and delete the contents. We are going to start from scratch.

In our hello-world example, we need to set an environment variable AIRWAVE_HW_PORT so our server knows which port to serve traffic on. This is something the developer has decided and is just a part of the app. Nothing significant here other than it’s a key:value pair in a configmap.

current configmap.yaml
added key:value pairs in values.yaml

Looks like we will have to do a little refactoring here because Helm says:

Variables names should begin with a lowercase letter, and words should be separated with camelcase:

So now…we have this.

values.yaml with a camelCase key

Remember, we are just configuring helm templates. You don’t have to change anything in your application.

Create a configmap template if you are using one

Helm has supplied a bunch of files, but there are a few that don’t come prepackaged. One of those is a configmap.

If you are already using a configmap, copy and paste yours as the following:


In our app, our current configmap looks like this:

our configmap.yaml again

We need to turn this into a template.

using the new value camelCase value

Let’s test our changes in the command line.

helm install --dry-run — debug hello-world .\hello-world -f hello-world\values.yaml

What just happened?

Let’s break down the command first:

helm install --dry-run — debug hello-world .\hello-world -f hello-world\values.yaml

  1. We attempted to install the chart, but used the --dry-run parameter so it’s not actually going to install anything.
  2. All we have is a configmap so it would’ve installed a configmap without --dry-run
  3. hello-world is the name of your chart
  4. .hello-world\ is the path to your chart
  5. -f hello-world\values.yaml is telling helm you want to use this values file.

What are those curly braces in the template?

  • values.yaml is where all your data lives
  • the curly braces basically says replace this with the values defined. Here it’s fromValues(from the values.yaml file).airwaveHWPort(the key inside of the values.yaml file).

If it’s still hard to follow along, just stay with me.

If you get an error like this while testing, it’s because you already have a configmap with the same name deployed.

More Templates

Just like how we copied our existing configmap.yaml to /hello-world/templates/configmap.yaml we need to do the same for some of the other files we need.



Here’s what it looks like without any edits.


I changed

- containerPort: 4998


- containerPort: {{ .Values.airwaveHWPort }}

It just so happens app our container port and airwaveHWPort: 4998 in values.yaml are the same. I’m substituting that value here to provide an easy example so you can understand how Go (the programming language) templating works. If I were to completely finish off this template, I’d be tempted to create a specifickey:value pair for the container port that was something other than reusing airwaveHWPort: 4998, but in the future, this is a decision you will get to make.




I changed

targetPort: 4998


targetPort: {{ .Values.airwaveHWPort }}

As before, we basically switched out the port number because airwaveHWPort: 4998 is the same value. If I wanted to continue on, I would create more key:value pairs for each parameter.


helm install --dry-run — debug hello-world .\hello-world -f hello-world\values.yaml

confimap, service, and deployment files have interpolated the values.

Deploy it

helm install --debug hello-world .\hello-world -f hello-world\values.yaml

lots of output

You can see here we have created 3 resources:

  • deployment
  • service
  • configmap
proof the 3 resources were created

Package it

helm package hello-world\

That’s it, everyone. Wow, what a lesson. If our app were something serious, we would probably build out many more key:value pairs, logic, and NOTES (instructions) on how our application should be deployed but since we are just testing things out, I’ll just leave it as is.


Today, we learned:

  • how to create a Helm chart
  • how Helm values work
  • how to turn your existing Kubernetes manifests into Helm templates
  • how to deploy your chart
  • how to package your chart

To delete

helm delete hello-world

Next Steps

We would need to send this chart to some kind of Helm repository so that we can reach it from any server that has access. With all that we covered, I will leave you all with this.

Until next time!

If you like this article, don’t forget to clap and follow!