Create Helm Chart


Create helm chart

In this tutorial, we are going to discuss how to create helm chart. In the earlier tutorial, we discussed various components involved as a part of the helm.

Create Helm Chart

Now it’s time to get more details about the charts, creating a custom chart, and the syntax and the various components within the charts.

This will be the main section within these particular helm tutorials, where we are going to have a detailed discussion about every component within a chart.

So I’m going to create a custom project and get more details about various files available as a part of the charts and how to use them. Then we will start creating a chart from scratch.

Let me get into the machine where I do have the helm installed. Here I will be issuing the following command.

$ helm create mychart
Creating mychart

So above command going to create a chart with the name mychart and put that within a folder called mychart. So here, mychart folder got created.

Verify Chart Files

If I get into this specific folder, I will be having all the essential required files. This is by default, create a small chart with sample deployment, services, everything.

[email protected]:~$ cd mychart/

[email protected]:~/mychart$ ls
charts  Chart.yaml  templates  values.yaml

I will be using this specific structure, and then we will create a chart from scratch. Before that, let me get into the different folders and see what information will be available.

templates folder

The fundamental thing of charts is the templates that will be put within the templates folder. If I get into the templates folder, I will have some sample templates.

[email protected]:~/mychart$ cd templates/

[email protected]:~/mychart/templates$ ls
deployment.yaml  _helpers.tpl  hpa.yaml  ingress.yaml  NOTES.txt  serviceaccount.yaml  service.yaml  tests

For the time being, Let’s not worry about these templates, which got created by default. For understanding purposes, let me cat a sample deployment.yaml file.

[email protected]:~/mychart/templates$ cat deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "mychart.fullname" . }}
  labels:
    {{- include "mychart.labels" . | nindent 4 }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  selector:
    matchLabels:
      {{- include "mychart.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      {{- with .Values.podAnnotations }}
      annotations:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      labels:
        {{- include "mychart.selectorLabels" . | nindent 8 }}
    spec:
      {{- with .Values.imagePullSecrets }}
      imagePullSecrets:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      serviceAccountName: {{ include "mychart.serviceAccountName" . }}
      securityContext:
        {{- toYaml .Values.podSecurityContext | nindent 8 }}
      containers:
        - name: {{ .Chart.Name }}
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default Chart.AppVersion }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
      {{- with .Values.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
      {{- end }}

It’s going to have the deployment.yaml file, which is templatized. For example, I have a variable that will read from some value files or other chart templates within the name.

Don’t worry about this particular syntax; what is it? We will be having a detailed discussion about every component of it. This is just to have a feel, how a template would look like.

charts folder

Within the charts folder, we will have all the dependent charts this particular main chart depends on. And this specific folder is empty.

[email protected]:~/mychart/charts$ ls
[email protected]:~/mychart/charts$ 
values.yaml

Now within values.yaml file will provide the values for the templates, and we can have hierarchical value; this is of json format.

[email protected]:~/mychart$ cat values.yaml 
Default values for mychart.
This is a YAML-formatted file.
Declare variables to be passed into your templates.
replicaCount: 1
image:
  repository: nginx
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
  # Specifies whether a service account should be created
  create: true
  # Annotations to add to the service account
  annotations: {}
  # The name of the service account to use.
  # If not set and create is true, a name is generated using the fullname template
  name: ""
podAnnotations: {}
podSecurityContext: {}
  # fsGroup: 2000
securityContext: {}
  # capabilities:
  #   drop:
  #   - ALL
  # readOnlyRootFilesystem: true
  # runAsNonRoot: true
  # runAsUser: 1000
service:
  type: ClusterIP
  port: 80
ingress:
  enabled: false
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  hosts:
    - host: chart-example.local
      paths:
      - path: /
        backend:
          serviceName: chart-example.local
          servicePort: 80
  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local
resources: {}
  # We usually recommend not to specify default resources and to leave this as a conscious
  # choice for the user. This also increases chances charts run on environments with little
  # resources, such as Minikube. If you do want to specify resources, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
  # limits:
  #   cpu: 100m
  #   memory: 128Mi
  # requests:
  #   cpu: 100m
  #   memory: 128Mi
autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 100
  targetCPUUtilizationPercentage: 80
  # targetMemoryUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}

I can read any value using the key hierarchy. We will be having a detailed discussion on how to read a specific value or array of values later point in time.

chart.yaml

In chart.yaml, we will be having various information like what API version, name, description. These three fields are mandatory. Additionally, we can have other fields like keywords type, what Kube version to use, different dependencies we can add, and who the maintainer is, and all those values are optional.

While discussing this specific file chart.yaml, we will be having a detailed discussion about every field added to this particular file.

So like this, we can have other files as well, like license, readme.md, values.yaml, values.schema.json crds folder, and templates.

Create new helm chart
license

So license is an optional file that’s going to have the license information about this particular chart.

readme

Readme, as the name suggests, is a human-readable text file where We will have information about this particular chart.

values.schema.json

values.schema.json is an optional file, but that’s a very important file where it will derive or drive how the structure of the values.yaml file will be. That is something like a schema definition file.

crd folder

Another folder that we did not see in the default chart that got created. That is crds that are going to have the custom resources that are required for this particular chart.

Create Helm Chart

Scroll to top