📋 JayJay's DevOps Diaries ..

Chronicling my journey through Cloud Native Infrastructure.. one step and tool at a time...

May 5, 2026 - 9 minute read - Kubernetes DevOps Networking

☸️ For the HELM of it - PART 2

Intro

In the last article, titled: For the Helm of it, I successfully demonstrated how to deploy a single Web-Application - WebApps at random from the DockerHub Artifactory using Helm Charts templates.

And by thus doing, we managed to demonstrate with Screenshots :

  • Creating a Helm chart template

  • Modifing the Helm template to accomodate a custom Web Application of our choosing

  • Appended /etc/hosts file to facilitate DNS resolution to hostnames maltina.app1 and maltina.app2

  • Enabling Ingress to accept external web traffic

But that was not the promise of that article, if you’d recall I promised demonstrating 2 apps on the same ingress at once.

In this segment, we are going to achieve that purpose. We are going to modify templates from the previous article ( For the Helm of it ), to accommodate additional deployments and services, enabling us to achieve our goal.

And after that, we can let all our imagination run wild. Manipulate ingress paths to our hearts desires. Abuse the power and priviledges knowledge provides..

By the way

I strongly recomend you familiarise yourself with some of thise Helm cheat sheets. They’ve been intrumental to my understanding on Helm charts.

Now for that Twist !! .. (get it? the twist from the last article?)

I wish I could boast this is going to be a straight forward article, citing how easy it would be, with just a wave of a wand (Harry Potter’s fans, I salute thee) but no its not. They are going to be a couple of conventional changes and alteration that can be a little mind-bending but hey, dont worry, I got your hand, and very happy to guide you through this tumultuous period I know how hard its going to be for you. ( trust me I do LOL )

And we are going to do so in a couple of steps.

Step 1 : Make a backup


Before we commence this journey, let’s start by making a backup of whatever working theory we have now. If youre using Git or some kind of version control tool like me then, you might want to skip this step.

If youre not, then you might want to make a backup of the multina directory created in the previous article. If things get messy and you loose the trail, discard the current directory and salvage your work from the backup.

so run this commmand

#if you're still in the working directory, go back by one step
#if you're outside skip this command

cd ..

#Now make a backup copy of multina folder called multina-backup

cp -r multina multina-backup

# get back into multina

cd multina

A screenshot of what you should have

Step 2 : Change the diretory structure


Cool, next we going to proceed with some spring cleaning. We are going to :

  • Create some directories inside some directories. each app would have it’s directory
  • Create supporting files for each directory, basically for each app.
  • Modify the Values.yaml file to reflect changes to :
    • The ingress paths for each app
    • Each app, to its own Service

This is the Screenshot of the Tree structure of the current directory.

Check the Helm status before we proceed

as we can see, we have one app running on the single delpoment.

Step 3 : Create folders, Copy files


So, the next steps are :

  • Go into the templates directory
  • Create a directory called app1
  • Move, (not copy) these 2 files into that directory
    • deployment.yaml
    • service.yaml
  • now duplicate app1 directory calling it app2

so we’ll end up with 2 new directories app1 and app2 with 2 files in them each with deployment.yaml and service.yaml

Issue these commands


# jump into templates
cd templates/

# make new folder called app1
mkdir app1

# move deployment.yaml into it
mv deployment.yaml app1/

# and service.yaml
mv service.yaml app1/

# make a copy of app1, call it app2
cp -r app1/ app2

A screenshot looks like this ..

The new tree structure will now look like this.

Step 4 : Back to Values.yaml


So far, everything looks good. but we have to tie everything together. If we re-trace our steps back to the previous article, you would see that everything in the end converges at Values.yaml.

Go to Step 5 of the last article to refresh your memory.

Sadly, it may seem that we might have to re-write the entire Values.yaml file. Thats if we dont succeed by writting some of it. And the reasons are stated in Step 2 and Step 3 of this article. Since the files and directory structure has changed, the way Values.yaml may traverse to find things would have to change to.

And the affected aspects of the file are :

  • Ingress : its a multi-app deployment, so each deployment has a service and each service has to be mapped to an ingress path.

  • Service : Yes, each service tells ingress which app its referencing on which deployment.

  • Deployment : YOu know what? How about I just show you in the Values.yaml file

Again, please go to Step 5 of the last article to refresh your memory of the existing *Values.yaml file, because I am just going to jump into the edited aspects of it.

Without further ado, these are the contents of the new, revised Values.yaml file

# values.yaml

# Global configurations (optional)
global:
  imagePullPolicy: IfNotPresent

serviceAccount:
  create: true
  name: ""

# Configuration for App 1
app1:
  replicaCount: 2
  image:
    repository: docker.io/burgxy/webapps
    tag: "v3"   # Replace with your actual image tag
  service:
    type: ClusterIP
    name: app1-svc # This name is used by the ingress template
    port: 80

  autoscaling:
    enabled: false # Set to false if not using autoscaling
    minReplicas: 1
    maxReplicas: 5
    targetCPUUtilizationPercentage: 80
  # Add any other app1 specific configurations here (e.g., resources, probes, env)

# Configuration for App 2
app2:
  replicaCount: 2
  image:
    repository: docker.io/burgxy/webapps
    tag: "v4"   # Replace with your actual image tag
  service:
    type: ClusterIP
    name: app2-svc # This name is used by the ingress template
    port: 80

  autoscaling:
    enabled: false # Set to false if not using autoscaling
    minReplicas: 1
    maxReplicas: 5
    targetCPUUtilizationPercentage: 80


# --- INGRESS CONFIGURATION ---
ingress:
  enabled: true
  ingressClassName: "nginx" # Specify your ingress controller class name (e.g., "nginx", "traefik")
  annotations: {}
    # Example annotations:
    # nginx.ingress.kubernetes.io/rewrite-target: /
    # nginx.ingress.kubernetes.io/ssl-redirect: "false"
  hosts:
    - host: maltina.app1 # Hostname for App 1
      paths:
        - path: /
          pathType: Prefix
          serviceRef: app1 # This helps the ingress template decide which app's service to use
          serviceName: multina-app1 # Explicitly state the service name for this path
          servicePort: 80
    - host: maltina.app2 # Hostname for App 2
      paths:
        - path: /
          pathType: Prefix
          serviceRef: app2 # This helps the ingress template decide which app's service to use
          serviceName: multina-app2 # Explicitly state the service name for this path
          servicePort: 80

  tls: []

A closer screenshot of the top of the file with line numbers for futher reference

and closer screenshot of the bottom of the file with line numbers for reference too.

.

A short explanation on each line on the new Values.yaml file

Let’s start from the TOP.

We have :

  • Line 7 : The ServiceAccount line. this was created or put in there to automatically create and overide any service account.

  • Line 12 & 30 : app reference These are declarations stating where each new apps begin.

  • Line 13 & 31 : replicaCount: add or modify this lines to state the number of replicas of the same image you want running. In this case, I put 2 each.

  • Line 15 & 33 : repository : This is the actual image we are pulling from DockerHub Artifactory. I am using WebApps my custom app, so for all foreseeable demonstrations, each image would be docker.io/burgxy/webapps

  • Line 16 & 34 : The version Tag for each image. this is the only time we differentiate one image or version from the next. They are over 7 images to choose from. the cool ones start from version 3 onwards.

  • Line 19 & 37 : service name : the service name for each deployment.

  • Line 48 : ingress: To enable ingress

  • Line 56 & 63 : host : Remember the hostnames we appended in /etc/hosts file ? maltina.app1 and maltina.app2 ? this is where we list them respectively.

  • Line 58 & 65 : hosts path of each app on each host.

  • Line 60 & 67 : serviceRef : Where to find the refered service

  • Line 62 & 69 : servicePort : to expose the port number, making the app accessible.

Step 5 : Have Access to the code. Go play with it !

For the sake of brevity all files can be found at our GITHUB Page

I’ve got the code from both PART-1 and PART-2 (This current part) pushed into github.

  • The PART-1 directory has got
    • The blank template version of the code
    • The version of the Single App Working
  • Where-as PART-2 directory has got :
    • The backup of the single app working
    • And the version of the succesful 2 apps working

Step 6 : Now tweak deployment.yaml and service.yaml templates

Before we get to deploy the second phase of our amazing app, we obviously need to tweak a few templates and make other minor adjustments before they can work. I must confess, this is the part I tweaked and googled a lot.

Some errors were just duh !! and straight forward. I knew instantly what I done or configured incorrectly. Others required a bit to extra thinking. I mean, I had done this a few times before, why embarass me now.

Anway, a couple of things I did, in no specific other was :

  • Deleting a few unwanted or bloated files
  • Changing the hierachical paths of every template variable that referenced values.yaml file.
  • Amending and modifying template’s name tags so it

The files deployment.yaml and service.yaml templates exist behind their respective directories app1 and app2. Somehow,

Step 7 : Now, deploy it !!


First check the privious status of the deployment

helm status multina -n multi-app

After a few run attempts, tweaking of the templates, deletion of some, finally deployed both apps working.

helm upgrade --install multina -n multi-app .

And IT WORKS !!!

First we have the output of the FQDN - http://maltina.app2/

Then we have still have the famous output from Part 1 - http://maltina.app1/

Step 8 : Honourable Mentions and Debug Proceedures

However,I did have to tweak some of the templates a bit to get it working, it wasnt straight forward, I did have a few bruised elbows and scraped knees.

For instance