Helm

Customizable component for Helm Charts

Introduction

Helm is an open source package manager for Kubernetes which enables users to provide, share, and use software built for Kubernetes. It functions as a templating engine for Kubernetes manifests, assisting in managing resources within a cluster.

Bunnyshell allows you to easily deploy applications by using your Helm Charts within our platform. It currently functions with Charts from the following sources:

  • Git repositories. Add Helm Charts stored inside your Git repositories. Example of a Helm chart added from a Git repository.
  • Helm registries. Add Helm Charts stored inside a Helm registry (Artifact HUB, for example). Example of a Helm chart added from a Helm registry.

Helm components are defined and edited only from the bunnyshell.yaml file. Bunnyshell allows you to declare a set of bash commands to be ran when deploying, starting, stopping, or deleting the component.

πŸ“˜

Note

Bunnyshell will not build the images for these components automatically, so you will need to add a Docker Image Component, or use one of your own images. See Docker Image Components for more details.

  • Helm components can be automatically updated and redeployed when a git webhook is received - on condition that the environment's auto-update feature is enabled.
  • They can be cloned automatically when ephemerals are created, but they can also trigger the creation of ephemeral environments.

Examples

To make it easier to understand how Bunnyshell integrates with Helm, we included two examples below: one is a Helm chart added from a Git repository, the other is a chart added from a Helm registry.

Helm chart added from a Git repository

-
    kind: Helm
    version: v1
    name: my-app-release
    runnerImage: 'dtzar/helm-kubectl:3.8.2'
    deploy:
        - |
            cat << EOF > my_values.yaml
                env: bunnyshell
                serviceImage: {{ components.my-app-image.image }}
                replicas: 1
                ingress:
                    className: bns-nginx
                    host: my-app-{{ env.base_domain }}
            EOF
        - 'helm upgrade --install --namespace {{ env.k8s.namespace }} --dependency-update --post-renderer /bns/helpers/helm/add_labels/kustomize -f my_values.yaml my-app-{{ env.unique }} .'
        - |
            SERVICE_LB_IP=$(kubectl get services --namespace {{ env.k8s.namespace }} my-lb-service --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
    destroy:
        - 'helm uninstall my-app-{{ env.unique }} --namespace {{ env.k8s.namespace }}'
    start:
        - 'helm upgrade --namespace {{ env.k8s.namespace }} --post-renderer /bns/helpers/helm/add_labels/kustomize --reuse-values --set replicas=1 my-app-{{ env.unique }} .'
    stop:
        - 'helm upgrade --namespace {{ env.k8s.namespace }} --post-renderer /bns/helpers/helm/add_labels/kustomize --reuse-values --set replicas=0 my-app-{{ env.unique }} .'
    exportVariables:
        - SERVICE_LB_IP
    gitRepo: 'https://gitlab.com/aris.buzachis/neo-dev-test.git'
    gitBranch: master
    gitApplicationPath: /

Helm chart added from a Helm registry

-
    kind: Helm
    version: v1
    name: my-redis
    runnerImage: 'dtzar/helm-kubectl:3.8.2'
    deploy:
        - |
            cat << EOF > my_values.yaml
                master:
                    replicaCount: 1
                replica:
                    replicaCount: 3
            EOF
        - 'helm repo add bitnami https://charts.bitnami.com/bitnami'
        - 'helm upgrade --install --namespace {{ env.k8s.namespace }} --post-renderer /bns/helpers/helm/add_labels/kustomize -f my_values.yaml my-redis-{{ env.unique }} bitnami/redis --version 17.3.6'
        - |
            REDIS_IP=$(kubectl get svc --namespace {{ env.k8s.namespace }} my-redis-{{ env.unique }}-master -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    destroy:
        - 'helm uninstall my-redis-{{ env.unique }} --namespace {{ env.k8s.namespace }}'
    start:
        - 'helm repo add bitnami https://charts.bitnami.com/bitnami'
        - 'helm upgrade --namespace {{ env.k8s.namespace }} --post-renderer /bns/helpers/helm/add_labels/kustomize --reuse-values --set replica.replicaCount=3 --set master.count=1 my-redis-{{ env.unique }} bitnami/redis --version 17.3.6'
    stop:
        - 'helm repo add bitnami https://charts.bitnami.com/bitnami'
        - 'helm upgrade --namespace {{ env.k8s.namespace }} --post-renderer /bns/helpers/helm/add_labels/kustomize --reuse-values --set replica.replicaCount=0 --set master.count=0my- redis-{{ env.unique }} bitnami/redis --version 17.3.6'
    exportVariables:
        - REDIS_IP

Component attributes

gitRepo

The URL of the Git repository where the Helm chart is located. This field is mandatory if you add the Helm chart from a Git repository. The repository will be cloned in the workdir of the runner image.

gitBranch

The branch where the Helm chart is located. This attribute is relative to the gitRepo. This field is mandatory if you add the Helm chart from a Git repository.

gitApplicationPath

The path to the application folder, relative to the branch. This field is mandatory if you add the Helm chart from a Git repository. When provided, it will watch for changes only within this folder to trigger Auto-updates (if enabled) or to display that a new version of your application is available.

:warning: The repository will be cloned entirely, not just the specified gitApplicationPath.

runnerImage

This is where you specify the image where Bunnyshell runs the commands given by the user. It can be the actual image of the component, or any other image.

If the value provided for runnerImage is '@self', Bunnyshell will reference the image of the component.

Commands

In the Deploy, Start, Stop and Delete properties you can add any type of commands. As mentioned before, you can deploy anywhere you want.

πŸ“˜

Note

Steps for the Deploy property are mandatory. The other properties can be left blank.

Below is an example that includes all the four properties mentioned earlier.

components:
  ...
  - name: component_name
    ...
    deploy:
        - |
            cat << EOF > my_values.yaml
                master:
                    replicaCount: 1
                replica:
                    replicaCount: 3
            EOF
        - 'helm repo add bitnami https://charts.bitnami.com/bitnami'
        - 'helm upgrade --install --namespace {{ env.k8s.namespace }} --post-renderer /bns/helpers/helm/add_labels/kustomize -f my_values.yaml my-redis-{{ env.unique }} bitnami/redis --version 17.3.6'
        - |
            REDIS_IP=$(kubectl get svc --namespace {{ env.k8s.namespace }} my-redis-{{ env.unique }}-master -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    destroy:
        - 'helm uninstall my-redis-{{ env.unique }} --namespace {{ env.k8s.namespace }}'
    start:
        - 'helm repo add bitnami https://charts.bitnami.com/bitnami'
        - 'helm upgrade --namespace {{ env.k8s.namespace }} --post-renderer /bns/helpers/helm/add_labels/kustomize --reuse-values --set replica.replicaCount=3 --set master.count=1 my-redis-{{ env.unique }} bitnami/redis --version 17.3.6'
    stop:
        - 'helm repo add bitnami https://charts.bitnami.com/bitnami'
        - 'helm upgrade --namespace {{ env.k8s.namespace }} --post-renderer /bns/helpers/helm/add_labels/kustomize --reuse-values --set replica.replicaCount=0 --set master.count=0my- redis-{{ env.unique }} bitnami/redis --version 17.3.6'

Displaying Components' resources in the UI

For Bunnyshell to be able to discover the resources this Helm chart installs in your cluster, we need the resources created by the chart to have a certain set of labels set on them. Make sure you replace the COMPONENT NAME section with the actual name of your component.

- app.kubernetes.io/part-of = env-{{ env.unique }}
- app.kubernetes.io/instance-<COMPONENT NAME> = bns

You can use the Bunnyshell-provided Helm post-renderer script to add the labels, with the helm install --post-renderer argument. Example:

--post-renderer /bns/helpers/helm/add_labels/kustomize

Value Interpolation for Docker Images

If you are using Bunnyshell to build your images using Docker Image, you can use value interpolation as exemplified below. NAME represents the component name of your Docker Image Component. Bunnyshell will replace it with the built image.

  • {{ components.NAME.image }}: contains full image name, including the tag.
    Example: nginx:latest
  • {{ components.dev_test_image.imageName }}: contains only the image name.
    Example: nginx
  • {{ components.dev_test_image.imageTag }}: contains only the image tag.
    Example: latest

Injecting Bunnyshell Variables in your resources

If you need to inject Bunnyshell environment variables in your resources, please refer to the Value Interpolation page.

- |
    kustomize edit add patch --kind Deployment --name man-web-self \
      --patch '[{"op": "add", "path": "/spec/template/spec/containers/0/env/-", "value": {"name": "ENV", "value": "bunnyshell"}}]'

exportVariables

Using this property you can export variables from Helm Components to other components inside the environment. They are captured only during the deploy and can be used after they reach the next interpolation context in the same deploy workflow, or in subsequent start/stop/destroy workflows.

πŸ“˜

Note

These are not environment variables, but variables exported from your deployment script.

Example: In the section presented above, under deploy, we defined the variable REDIS_IP.

deploy:
    - |
        cat << EOF > my_values.yaml
            master:
                    replicaCount: 1
                replica:
                    replicaCount: 3
        EOF
    - 'helm repo add bitnami https://charts.bitnami.com/bitnami'
    - 'helm upgrade --install --namespace {{ env.k8s.namespace }} --post-renderer /bns/helpers/helm/add_labels/kustomize -f my_values.yaml my-redis-{{ env.unique }} bitnami/redis --version 17.3.6'
    - |
        REDIS_IP=$(kubectl get svc --namespace {{ env.k8s.namespace }} my-redis-{{ env.unique }}-master -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

Normally, this variabile would only run here. But in our case, we are going to list it under exportedVariables.

exportVariables:
            - REDIS_IP

This way, after deployment Bunnyshell will store the variable (encrypted) in a database. The variable will be available for you to use in another component, if need be. You can use the exported variables in interpolation contexts using key with the format below:

{{components.NAME.exported.VAR_NAME}}

Helm Components also have Environment Variables. Environment Variables are injected in runnerImage.

Usually, environment variables are injected in Kubernetes, where Bunnyshell starts your pod with the image it built. All Component, Environment and Project variables are inherited.


Resources

Resources are fully managed by Helm

Resource cleanup

If Helm upgrade is used, the resource cleanup will work out-of-the-box.