Loading video player...
Hello everyone, welcome back to my
YouTube channel. So in today video we
are going to discuss how we can deploy
same docker image on multiple
environment using helum charts. So we
are going to deploy this application on
AKS cluster and for multi-environment
setups we are not going to create a
separate AKS clusters. I already spin up
a one single AKS clusters. So what we
are going to do we are going to create a
name spaces. So one name space we will
create for dev environment. Another name
space we will create for test
environment or maybe QA environment. So
we will have a separate environment
without having multiple AKS clusters.
And this is also a best practices if you
are working on realtime projects.
Definitely you are not going to create a
separate AKS cluster for your dev
environment and another AKS cluster for
Q environment. then another for maybe
SIT environment. So for prod environment
definitely we need to set up a separate
AKS clusters with limited access. But
for dev environment and cube environment
generally we use a name spaces to
segregate the environments. So that's
what same we are going to achieve as
part of this video.
Okay. So what we need to set up this
complete whole pipeline basically. So we
need a Azure account and subscription,
Azure DevOps organization and project
and AKS cluster, Azure container
registries where we are going to uh
store our Docker images and on AKS
cluster basically we are going to deploy
our docker images. Then we need a
service connection multiple name spaces
like it's all up to you if you want to
deploy on two environments you will
create a two name spaces then finally
you need a application code with Helm
charts. So few things I have I already
have it like uh these four parts
basically. So I have Azure account I
have Azure DevOps organization and
projects. I have already spin up a AKS
cluster to save some some time basically
and Azure container registry as well. So
let's quickly verify.
So let me go to container registry
first. So I have container registry
called demo ACR121
and I have AKS cluster as well which is
of my AKS clusters but we don't have any
name spaces apart from default name
space. So if I'll go to name spaces
here.
So we don't have any dev and q name
space. So those nameace we are going to
create with the help of helm charts
using namespace manifest file.
So and next thing we need a service
connection. So let's create a service
connection first. So for that we have to
first go to project settings and under
pipeline you will see option called
service connection. So for
uh Azure DevOps to Azure cloud basically
we are going to use this service
connection Azure service connections and
if you see the IDL is 29C4. So when you
create a service connection basically
you will add this ADO or project as a
app app registration in uh Azure AD or
Azure in id. So what we will do because
we cannot use Azure service connection
for docker registry. So for docker
registries anyways we need to create a
new service connection. So before that
uh let me go to intra id first
and if I'll go to app registration here.
So under app registration we can see one
service principle which starts with 29
C4 and if I'll come here so same service
connections. So what we will do we will
use uh this service connections for AKS
deployment part and before that we also
need to add this service principle in uh
Azure container registries as well. So
let's add this service connection first
in both the services ACR and AKS. Then
we will create a new service connection
for ACR because ACR we cannot use Azure
resource manager as a service
connection. So here you can see this uh
service connection type is Azure
resource manager and we cannot use this
one. Another option is if you don't want
to use a service connection then you
have to authenticate your ACR Azure
container registries in your in your
pipeline.ml file. Basically you have to
login you have to pass uh credentials
then that way also you can achieve it.
But uh let's make it simple. So what I
will do first? First I will add this
service principle in Kubernetes
services.
So this because this service principles
we are going to use in our Azure
pipeline and this service principle
should have access on AKS cluster to
create or deploy resources. So let me go
to access control
and here I will add a role assignment
and here under the job function role you
can see a different roles but what we
will do here we will simply assign a
contributor permission
because contributor has most of the
permission which is required and here I
will choose a member which is our
service principle.
Let me select it
and review and assign.
Okay. So we have assigned a service
principle to AKS with contributor
access. Now similarly we need to assign
this service principle
on ACR as well with contributor
permission.
Okay. So, we have to create another
service uh connection for docker uh
sorry azure container because we cannot
use this service connection on ACR
because uh it is Azure resource manager
type. So for that what we will do uh we
will create a new service connection
here and we will look for docker
registry option here
and here I will search for azure
container registry and let me select
authentication type is service
principle.
So now it will ask me for a username and
password. So I will enter it for my uh
Azure account details like email id and
password.
Okay, let me send the code here.
Okay. So the code is 3 5 8 7 2 1.
Okay. So once it's successful then you
can see a drop-down for Azure container
HTS. So by default when we create this
uh service connection docker HD service
connection it will already have a push
and uh pull permissions basically. So
let me select my container registries
and let me give a name demo ACR
and let me grant a permission to all
pipeline.
So as soon as this connection setup will
be completed you will see another
service principle
uh on on sorry under app registration.
So let me go to app registration here.
So you can see this is the new service
connection which we have created for
docker sorry uh docker h or your
container h basically.
So this is completed and if you see the
users history also so it will be limited
to this particular
uh what is called ACR only it will not
have access on your azure kubernetes
services. If I'll go to here access
control and if I'll come to role
assignment parts.
So this is the service connection which
we have created. So you can see this
service principle only have permission
to this resource itself. But this is the
main service connection which we have
created. This service connection has a
inherit permission from a resource group
level. So this is the difference.
Okay. So now we have a service
connection.
Now we need to create a multiple name
spaces. So which we will create uh using
a pipeline. So let me quickly move to my
repository
and let me give a quick overview of
application source code. So this is a
simple NodeJS application. So you can
see we have only two files server.js and
package.json JSON file and another we
have a docker file to generate a docker
image to sorry a build a docker image.
So what we are going to see here? So we
are simply going to uh like whenever we
once that application will be deployed
we will see this output on our browser
screen. This is what we can we we are
going to achieve. So or in simple words
we are going to print
this statement when we browse our
application.
And if I'll go to package file so here
we generally specify the dependencies.
So we have we have only single
dependencies here. Now this is the name
of your application, version,
description and all and here you can see
the script. So basically this will be
the file which will execute it when our
container or pod will start. So as soon
as this part this server js file will be
triggered, it will
output a message which we want. So this
is the message which it will pop up on a
browser screen. And if I'll come to a
docker file. So here we are going to use
node 18 alpine docker image which is a
base image. And we are going to create a
work directory with the name of / app
inside a container. Then we are copying
our package. file inside this particular
directory. Then we are going to install
a dependencies and then we are here
basically copying our application source
code. Nothing but these two files. And
this is the local port. So like when you
want to run this application on your
local system, it could be your visual
studio in that case this will be a local
port where you can access this
applications. This is not a
AKS deployed pod port number that will
be a separate different
and this is the command line argument
because when the container or the pod
will start it will go and trigger this
file server.js. JS.
Okay. So this was our application source
code part. Now let me come to Helm part
here.
So let me go to template section first.
So under template you can see we have
four files. So one file we have for
deployment. Another file we have for
name spaces and third we have a
service.ml. Now another file here we
have underscorehelpers.tpl.
So here basically we define our named
template. If I'll open this file. So
like name template are something similar
to a function which we create in general
programming language like instead of
repeating your same codebase again and
again on multiple places you can simply
create a function and call that function
from multiple places. So same thing we
are going to achieve uh using this
helpers.tpl file. So I just want to
include a named template thing how we
can reference in helum charts that's why
we have taken a simple uh name template
here. So what I'm going to do here so
basically we are defining a name my app
dot name. This is the function or name
template which we have defined and the
value will be my app.name will be
dotchart dotname. So in our case if I'll
go to a chart.ml file. So my app name is
my app. So this will be the name. So
this value basically we are using in
namespace.ml file. So I'll come to this
part little later. Let me first explain
this one. And here we are ending this
name template. So these three lines
define we use to define a name template.
Here we define the actual values which
we want and this is the end statement.
Now let me come to a deployment.mml
file. So here we have again a API
version which is app/v1 kindage
deployment. Under metadata sections we
are getting a values like the name of
this deployment will be dot chart name
deployment. So dot chart will be the
value will come from this chart doml
file. So if you can see dot chart dot
name if I'll come to this file so the
the dot chart will be this part
basically dot chart and dot name and the
value of dot chart and dot name is my
app. So the deployment name will be my
app
deployment
and name spaces. So we have not created
a name spaces that's what first thing
like when we install our helm chart it
will go and look for this particular
value which is dot values dot namespace
dotname and this value basically it will
get from these values files. So this is
a multiple environment uh scenario
that's why we have created a two files
here values.dev.ml
file which is for dev environment and
values.qa.ml
file which is for Q environment and we
have a default values doml file. So in
general which like suppose we have a
docker image which is in common in both
the environments like we want to deploy
a same image on tab and Q. In that case
we can reference a docker image here.
Docker image in the sense a a registry
name like registry URL and repository is
going to same. So this will be the
common thing common name for both the
environment tab and Q
sorry. So whatever we have common in
both the environments we can define in
values.ml file and whatever we have a
environment specific those values we can
define in values dot dev.ml and values
doqa.ml. So if I'll come to here so if
you can see uh the nameace things which
will be a environment specific so
nameace is the value create hyphen uh
sorry create colon true name is Q. So
this is if the create value is true it
means it is going to create a name space
for you and name will be Q. So if I'll
come to a namespace.mml file
you can see here uh we have defined a if
condition here. So if dot valalues do
namespace dot create it means
it is going to reference our values
file. But one thing you will notice here
we are referencing our referencing this
file values.ml file. But in this file we
have not defined a name space things. So
by default what we have mentioned here
name space create false. So this is the
default file basically. So what we will
do in a pipeline we are going to
uh pass this particular file type. Sorry
not file type this particular file. So
it will override this one. So whatever
the things it is required from this file
which it will take and rest of the
things it will take from the
values.dev.ml
file. So here if you can see here we
have a name space thing is true but in
values.ml file we have which is false.
So it is going to take this file because
if I'll come to a pipeline.ml file for a
for time being. So if you can see here
in argument section we are passing our
values.dev.ml
file. By default, it will go and check
the value first on default values.mml
file and then it will come to a
values.dev.ml
files. So let me go back to a
namespace.mml file.
Okay. So this is the first condition
which we have specified. If dot values
dot namespace dot create then it is
going to create a condition. Sorry, it
is going to create a name space because
we have mentioned here dot create and
dot create value is true in values.dev.m
dev.ml file you can see if it is false
it is not going to create a name space
for you
and another thing if you you will see
under metadata sections not metadata
basically so here basically we are just
getting a name again simp from this
values doml file uh under labels we have
you can see include so include generally
we use to reference the name template
which we have defined under
help_helpers.tpl
file. So we are what we are going to
include we are going to include a name
template which we have defined. So what
we have defined here
my app dot name and if I will come to a
namespace.ml file. So here we have what
we have mentioned my app do.name and uh
dot here is a current scope basically.
So that's how basically we can reference
or we can include the name template from
helpers.tpl file to any manifest file.
This is a simple example which we have
taken. So I just want to cover a
condition and uh name template as well.
If you are not aware about much on helum
name template then I have already
created a playlist on helum. So if you
have not watched it you can go and watch
it. So you it will be a more clear how
basically name templates works.
Okay. So next file we have here is
service.ml file. So again we are getting
few values from chart.mml file and few
values from these two files like
values.ml and environment specific
values file. So I'm not going to explain
this file because this is pretty
straightforward. If you can see under
metadata we want a name of this service.
So the chart.tchart.name will be my app
-y service and name space. So it will be
dab or either Q based on the file which
we will pass in the arguments
chart. ML file. So here just simple we
have defined what app version is sorry
API version is what will be the name of
charts which and the type version app
version. So you can customize these
things based on the requirement. But
this is very important file. If you
don't have chart.ml file your helm
install will not work.
So there is only one difference in both
the files values. ML and values.qa.mml.
Under values.ml file I have specified
only simple single replica account. What
in values do qa.ml file I have mentioned
two replic account
and rest all the things is same like
service type will be load balancer port
will be 80 and name space here qa and
here we have a dab name space
okay now let me come to a azure pipeline
ml file this is important file so what I
will do let me create a pipeline first
then I will explain this file then it
will be more clear
okay before this Uh let me check one
more thing under values doml file uh ACR
repository name. So let me see the
container registry name here. So we have
demo ACR 121. Let me correct this value
first
otherwise our application will not work
because we will see error called image
pull back off. Now let me commit this
file.
Okay. Now let me go to pipeline and
create a new pipeline.
Uh let me select my repositories which
is AKS Helm multi-environment.
Okay.
Now let me do first one thing. Let me uh
minimize all the stages. So we will go
one by one of each stages. So the very
first thing is trigger which is main
your branch name. So as soon as you will
check in anything on this branch your
pipeline will trigger.
But if you want you can disable this
trigger as well.
Next is pool. So virtual machine image
because we are going to use here Azure
hosted agent. We are not going to use a
self-hosted agent here. And here we have
specified a few variables. But if you
want you can save this variable under
library variables. It is the best
practice. But for this demonstration I
have just mentioned here because I have
only few variables here. So the very
first thing is image repository. So
image repository will be the name of
image repository will be my app. So if
I'll come to ACR and repositories.
So here we don't have any repo yet. Once
we will uh run this pipeline it is going
to create a image sorry a repository
with the name of my app. Now nextly we
have a docker registry service
connection. So this is a service
connection which we have created for
ACR. So let me correct this value as
well. It might be a wrong. Let me go to
service connection. So this is demo ACR.
So let me copy this name.
Okay. Another service connection is AKS
service connection. This is basically a
service connection which we have create
which I have already created from Azure
DevOps to Azure cloud and same service
connection we are going to use for AKS
cluster as well. That's why we have
assigned a permission on AKS cluster as
a contributor role basically. So if I'll
come to here
this is Azure service connection
which is fine. Next we have a Helum
chart path. So I have Helm chart under
this location. Let me go to my
repository here. And under this repo I
have a folder called Helm and under Helm
I have a folder called my app. And under
this I have a Helm templates sorry Helm
charts.
So that's what I have specified a path
here. Okay let's explore the build stage
first. So here what we are going to do
we are going to build our docker image
and we are going to push our docker
image to ACL. So for that I'm just using
a simple task task which is docker. If
you simply search here
sorry docker. So this is the task which
I have used here. So let me go to
settings here. So the very first thing
here container registry. So we already
have created a service connection. So we
are just using this as a variable here.
Next is container repository. So
repository name we have created this
variable. So we are using image
repository variable here. Then next we
are using a command build and push. If
you want you can first build it then
push it. But we have a common task for
common command for build and post. So I
have used this one.
And here you need a docker file
location. So my docker file is under
this location app/doccker file. So if
I'll come to your app and under app we
have a docker file
and text here we are using build dot
build ID means the build number will be
our docker image version and tag and
latest test also. So both the text we
are going to use. This is what we are
going to as part of build and push our
docker image
and under settings sorry another uh
steps task behavior to install Helm
because we are going to use aure hosted
agent and we are not sure what all the
utilities installed on that particular
virtual machine. So for safe site
because we anyways we need a helum. So
we are going to install Helm utility on
the Azure hosted agent basically.
Okay. So now let me minimize this ST.
Let me go to deploy to dev stage. So the
very first thing is stage name display
name. You can give any name to here and
here as well. Now important thing here
is depends on. So we are this particular
stage is depend on build stage. Once
this stage will be completed
successfully completed then only this
stage is going to trigger that's why we
have mentioned the condition here
succeeded
under job section we have a deployment
job which is deploy job display name you
can give any name here involvement so
environment we are going to use this
particular so generally we use
environment to segregate our releases
and we are going to use a strategy here
run once
Then we have a deploy steps. There are
many strategies of available you can use
based on your requirement. These are
called a deployment strategy. If I
simply search here
deployment
strategy on sorry
Azure DevOps
pipeline.
So here you can see run once deployment
strategy which we are going to use uh as
of now. Then we have a rolling
deployment strategy. Uh then we have a
canary deployment strategy. So based on
requirement you can choose what kind of
uh deployment strategy you want. So in
our case we are going to use uh run once
as a deployment strategy.
Now under this uh you can see under
steps basically I'm going to check out
our repository as well because we need a
helm chart. So there are two option you
have either you can build and publish
sorry uh you can publish your Halum
charts on pipeline if you don't want on
build stage you can again check out your
code on this particular part sorry on at
deployment is deploy stage and you can
use from here as well.
Now we are going to again install a helm
on this particular agent.
So for that also we have a task helm
tool installer. So I'm using the same
dos task here. And then under settings
again we have a task package and deploy
helum chart. So I'm going to use this
built-in task. These are the built-in
task which is available in Azure DevOps.
So task name
display name you can keep keep any. Now
under inputs. So under input Azure
subscriptions. So I'm going to use a
service connection which we have
created. So this is the variable under
which we have stored. So if I'll come
here Azure service connection this is
the variable name and the value is Azure
service connection. So this is the
service connection which we have
created.
Now resource group I have hardcoded here
demo but if you want you can define in
top like here basically in variable
group again you can create another
variable called resource group and you
can define the values
and this is our cluster name which is my
AKS - cluster and then we have a command
so you can see here uh under command
section we have many commands create
delete expose get init and
So we are going to use a up upgrade
command. Why? Suppose like we are sure
like we have not deployed this Helm
charted but in case if it is already
deployed it is going to upgrade your
Helm chart. Chart type is file path. So
again we have two option here name and
file path. Why we are using file path?
Because we are going to use Helm chart
from your check out like on your build
agent. you will you are I'm going to
check out my repository. So that's why I
have chosen here file path and default
working directory is the location where
your azure repos will be checked out. So
here you we will have
uh this name aksh helm - multi-yment and
under this I have a folder called helum
then under helum I have a folder called
my app. So under my app I have complete
helm charts.
So you can see I have used here two
variables. This is the built-in
variables which is system.default
working directory and another variable I
have used helm chart path. If you want
you can simply specify a folder path
here like /helm/my
but I have already declared a variable
here with the location that's why I'm
using a variable here.
Now you have you need a unique release
name for your each uh release basically
on AKS. That's why this release name I
have put my app - tab and this is
important part part under arguments.
So
I'm going to use hyphen install because
we want to install our Helm charts
and this is the location of our Helm
chart. And if we will not specify this
values.tab.ml tab.ml file then this helm
chart is only going to consider
uh this default values doml file but we
have we are going to create this uh doc
simp sing single docker image on
multiple environments that's why we have
created a se environment specific values
doml file that's why I'm going to
reference my file name here so by
default it will go and search for the
values on default uh values this ML file
and then it will go and come to check
this particular file.
Another argument here we are using
override.
So here we you can see we have override
as well somewhere.
Okay. So override is not there but if
you look for a documentation you can
find this one. So what we are going to
do if I'll come to here you can see
under text basically we have defined or
we have hardcoded a value 1.0.0 what
instead of this tag number we want our
build. build ID as a tag. That's why we
are going to override it with this
particular option. And here image tag
equal to build.build id. And image dot
tag if you come here image dot tag. So
this will be override.
Now we have a same file setup for
another stage which is our deploy to QA
stage.
So if I'll come to deploy to Q stage
just I have changed the names and the
conditions. So now in deploy to dev we
have a condition depends on deploy to oh
sorry depend on build stage. But here we
have mentioned a condition depends on
previous stage which is deploy to dev
and condition is succeeded. Once it is
succeeded the previous stage then only
it is going to trigger this particular
stage and rest all the fields are
remains same just we are just changing a
release name value here and the values
do qa.ml file because this stage is we
are going we have configured for QA
environment and again we are going to
override the build.build build ID.
Sorry, default tag with build.build ID
ID. Okay. So now let me uh save this
file.
Okay. Now uh let me go to environment
sections. So here we don't have any
environment but as soon as the pipeline
execution will be completed we will see
two environments here like AKS dev and
AK AKS Q environment. So let me trigger
my pipeline first.
So you can see involvement dev - a could
not be found. The environment does not
exist or it has not been authorized for
use. And similarly for here as well. So
okay.
Let me change the value here. Dab. And
let me change here QA.
Okay. My pipeline is valid.
Let me save it.
Okay. So the very first stage was build
and push our docker image.
So let me go to Asia. Let me refresh it.
Okay, it is not created a repository
yet.
Okay, I think there are many other
pipelines which is already triggered
because the CI part was enabled. Let me
delete this one first because if I'll
edit this and let me go to triggers
you can see uh if I will click here you
can see enable continuous integrations
by default when you create a pipeline uh
continuous integration will be
automatically will be enabled. So that's
why as soon as we have changed the value
of environment and we have checked in
the code it is already
uh triggered the pipeline. So let me go
back here. Build pipeline. Let me leave
this field.
Okay. So the build and push part is
completed. Let me go here and refresh
it. Okay. So we can see a repository my
hyphen app and build ID which is 104. If
I'll come here and look for build ID
which is 104. That's fine. Okay. Now let
me approve this stage.
So this is the first time when you
create any new pipeline you have to
approve these stages.
So it is going to take couple of
minutes.
Okay. So the deploy with sorry uh deploy
to dive stage is completed successfully.
uh let me go to
my cluster
and let's verify first a name space. So
let me go to name spaces.
So now we can see we it is created a
name space called dev and under dev name
space it is created a deployment which
is my app- deployment and under
deployment we can see our pod we have
single port because for dev environment
we have specified single replica account
and that's why here we have a single
replica set and for uh Q environment we
have specified two replica accounts so
let me approve this stage as Okay.
Okay. So now if I will go to services
here because we have used a service type
as a load balancer. So my app hyphen
services which is under dev name space
and it has a public IP address. So let
me browse my application.
So you can see this is the output we
want because this is the message which
we have passed in our server.js JS file.
So for QA also it is completed. Let me
go and refresh it. So you can see
another service name my app service. It
is created under Q QA name space. Now
you can see the benefit of name spaces.
We have a same service name but it is on
different name space. If if we are going
to create both the services in single
sorry in default name space then it is
going to be a fail. So it now this Q&A
name space service is also has a
different IP address which is start with
4.187
something. Let me browse this one as
well.
So here also you can see we are getting
a same message in both the IP address.
This is what we want as part of our
application source code.
And if I will come to environment parts.
So here you can see it is created two
environments DAB and QA. And you can see
the last activity 5 minutes ago. If I
will open dev environment.
And if I'll come here,
it is going to pop up this screen.
Sorry. this deploy to dev job because
this job was uh connected to dev
environment and deployed to QA was with
uh what is called QA stage basically. So
you can see all the changes and all
everything you can track here. That's
why this is the benefit of using
environments configuration. So it is
like uh it is easy to manage the
releases.
So you can simply see how many build how
many build numbers and all executed
under this environments. All these thing
you can track if you are going to use a
environments.
So I hope it's clear. In case if you
have any doubts, you can definitely ping
me on comment box and I will keep this
application source code link link on
GitHub. So you can go and if you want to
do hands-on with your own, you can do
that as well. So that's all for today.
See you next video. Thank you so much.
๐ In this video, weโll walk through Azure DevOps CI/CD with Helm & AKS and show you how to deploy your applications seamlessly across multiple environments โ Dev, QA, and Prod. Youโll learn step by step: โ How to set up a CI/CD pipeline in Azure DevOps โ Using Helm charts for Kubernetes deployments โ Deploying to Azure Kubernetes Service (AKS) โ Managing multiple environments (Dev, QA, Prod) efficiently โ Best practices for Helm + Azure DevOps integration ๐ GitHub Repository (Source Code & Helm Charts): https://github.com/shubhamagrawal17/Tutorial/tree/main/aks-helm-multi-env Whether you are a beginner exploring CI/CD or an engineer looking to streamline Kubernetes deployments, this tutorial will give you the complete hands-on guide you need. ๐ Donโt forget to subscribe for more DevOps, Azure, and Kubernetes tutorials! #DevOps #Helm #AKS #AzureDevOps #cicd #HindiTutorial #k8s #azure #kubernetes