Skip to main content

Creating a Helm Chart

Let's create our first chart from scratch and then we'll create a chart based on another one as a subchart.

The first thing we need to do is the directory structure.

mkdir meu-chart && cd meu-chart && mkdir templates charts && touch Chart.yaml values.yaml
tree
.
├── Chart.yaml
├── charts
├── templates
└── values.yaml

With the structure created, let's define some information about our chart inside the Chart.yaml file.

The possible parameters can be found at https://helm.sh/docs/topics/charts/.

Copy into Chart.yaml

apiVersion: v2
name: meuchart
version: v1.0
kubeVersion: >= 1.20.0
description: Create my first chart
type: application
keywords:
- study charts
- first chart
- learning charts
- hello world
home: https://gitlab.com/davidpuziol/study-helm/-/tree/main/meu-chart # optional
maintainers: # (optional)
- name: David Puziol
email: [email protected]
url: https://linktr.ee/davidpuziol
icon: https://cncf-branding.netlify.app/img/projects/helm/icon/color/helm-icon-color.png
appVersion: 'v1.0.0' # optional
deprecated: false

Now let's define our templates, which are in fact our manifests but referencing values from values.yaml. Create a deployment.yaml file inside templates with the following content:

Notice that values are referenced inside {{ }} and we have some to analyze.

To check possible values for .Release and .Chart, check the documentation at https://helm.sh/docs/chart_template_guide/builtin_objects/.

  • .Release
    • References the values received at installation time. It's something that isn't in Chart.yaml but was added at runtime as a parameter. An example would be --namespace meu-release. It will be accessed with .Release.namespace.
  • .Chart
    • References the chart values defined in the Chart.yaml file
  • .Values
    • References the values defined inside the Values.yaml file (default configurations) or from the file passed in the -f parameter at the time of Helm execution.
  • .Capabilities
    • References the kubernetes cluster or helm
  • .Template
    • Information about the template being executed. It would be like a self-reference.
apiVersion: apps/v1
kind: Deployment
metadata:
# This value comes from Chart.yaml
name: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}
release: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}
release: {{ .Release.Name }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http

Similarly, create a service.yaml file in templates with the content below.

apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
app: {{ .Release.Name }}
release: {{ .Release.Name }}

And now let's complete our values.

image:
repository: nginx
tag: latest
imagePullPolicy: IfNotPresent
replicaCount: 1
service:
type: NodePort
port: 80

Let's create it.

helm create meu-chart

We use the helm upgrade --install command instead of the helm install command because it already checks if the package is installed in the cluster, and if it is, it just performs the update.

If you want to see what will be applied without applying it, for a possible analysis or debugging we can use --dry-run and --debug.

helm upgrade --install meu-chart . --dry-run --debug > dryrun.yaml
helm upgrade --install meu-chart .
# Release "meu-chart" does not exist. Installing it now.
# NAME: meu-chart
# LAST DEPLOYED: Mon Dec 26 03:19:25 2022
# NAMESPACE: default
# STATUS: deployed
# REVISION: 1
# TEST SUITE: None

k get pods
# NAME READY STATUS RESTARTS AGE
# meu-chart-94b9bf4bb-lk8sp 1/1 Running 0 7s

If you want to test it.

kubectl port-forward svc/meu-chart <nodeport>:80

testnginx