🟦 Application Deployment in Azure Kubernetes Service (AKS)
What is AKS (Azure Kubernetes Service)?
Azure Kubernetes Service (AKS) is a managed container orchestration service provided by Microsoft Azure. It allows you to deploy, manage, and scale containerized applications using Kubernetes without needing to manage the underlying infrastructure.
Prerequisites:
- Install Azure Cli
To install Azure CLI using Winget, run the following command in Command Prompt:
winget install Microsoft.AzureCLI
- After installation, log into Azure to see if it's functioning by running below command:
az login
This will redirect to Microsoft Login page you will need to login to your Azure account.
Then run below command to Install kubectl using Azure CLI:
az aks install-cli
Creating AKS Cluster:
-
Go to https://portal.azure.com and sign in to your Azure account.
-
Navigate to Services > Kubernetes Services.

-
Click Create > Kubernetes Cluster.

-
On the creation page:
• Select the desired Resource Group.
• Choose a Cluster Preset Configuration (click Compare presets to evaluate options).
• Set the Cluster name (e.g., leasetool, SCMWebAPP) and Region (e.g., South India).

Node Pool Configuration
-
On the Node Pools page:
• Either add a new node pool or update the existing agentpool.
• Click the node name to update.

• Adjust Node Size by clicking on "Choose a size" based on the requirement and set Minimum Node Count and Maximum Node Count (e.g., 1 to 2).
• Click Update.

Networking Configuration
-
On the Networking page:
• Choose Azure CNI Overlay.
• If using AGIC (Application Gateway Ingress Controller) for SSL/Firewall, select Azure CNI with Node Subnet.

• Review and click Create. The process may take 5–10 minutes.

Deployment Process:
- Once AKS is created, perform the following steps in Command Prompt: Login to ACR(Here using Docker, can be replaced with respective container runtime to pull image):
docker login planvisage.azurecr.io --username <User Name> --password <Password>
Run this command to check the available containers in ACR:
az acr repository list --name <UserName> --output table
Login to Azure and set the subscription
az login
az account set --subscription <YourSubscriptionName>
(To get subscriptions: az account list --output table)
Get AKS credentials:
az aks get-credentials --resource-group <YourResourceGroup> --name <YourAksCluster>
• Create a Kubernetes Image Pull Secret:
First create a namespace under kubectl
kubectl create namespace pvtest
Now create Secret:
In Azure Kubernetes Service (AKS), a Secret is an object used to securely store sensitive data
kubectl create secret docker-registry acr-secret ^
--namespace=pvtest ^
--docker-server=planvisage.azurecr.io ^
--docker-username=<ACR UserName> ^
--docker-password=<ACR Password> ^
--docker-email=<Your Email>
• Create a folder and inside it create two YAML files one for deployment and another for services named as below:
deployment.yaml and service.yaml
• Create service.yaml file:
Sample service.yaml file
apiVersion: v1 # Uses the core Kubernetes API.
kind: Service # Defines a Service, which enables communication between components inside the cluster.
metadata:
name: leasetool-service # The name of the service.
namespace: pvtest # Add this if your deployment is in 'pvtest'
spec:
type: LoadBalancer # The service is accesible Public/ For AGIC and Private need to use: ClusterIP
selector: # Matches pods with the Label app: leasetool
app: leasetool # Any pods with this Label will be part of the service.
ports:
- port: 80 # The port on the service that other component will use.
targetPort: 8080 # The port on the pod where traffic is directed.
🔹 Optional: Using Application Gateway with AKS (Internal / Intranet Setup)
This section is optional and should be followed only if the application needs to be accessed internally (intranet) or requires centralized traffic control.
By default, the Service created in AKS exposes the application using a public Azure Load Balancer. If you want the application to be accessible only within a private network, or if you plan to use Application Gateway for routing, SSL termination, or firewall (WAF), Application Gateway can be integrated with AKS.
Important prerequisites for Application Gateway integration
-
AKS and Application Gateway must be deployed in the same Virtual Network (VNET) (They should be in different subnets, but within the same VNET)
-
Application Gateway will act as the entry point for user traffic
-
The AKS service should be internal, not public.
When using Application Gateway, update the service.yaml as shown below:
apiVersion: v1
kind: Service
metadata:
name: leasetool-service
namespace: pvtest
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
spec:
type: LoadBalancer
selector:
app: leasetool
ports:
- port: 80
targetPort: 8080
🔹 This annotation ensures that the service is exposed internally within the VNET, allowing Application Gateway to route traffic to it.
• Now create deployment.yaml file:
Sample deployment.yaml file
apiVersion: apps/v1
kind: Deployment
metadata:
name: leasetool #This is the name of the Deployment, can replace with the required ApplicationName (eg: SCMWebApp..)
namespace: pvtest
spec:
replicas: 1 #This speocifies that one pod should be running at all times
selector:
matchLabels:
app: leasetool #This is the name of the Application, can be replaced the required ApplicationName (eg: SCMWebApp..)
template: #This template defines how the pod should be created.
metadata:
labels: #Each pod will have labelapp: leasetool so that deployment can be manage it.
app: leasetool #This is the name of the Application, can be replaced with the required ApplicationName (eg: SCMWebApp..)
spec: #Pod specification
imagePullSecrets:
- name: acr-secret # ImagePullSecret: Secret Name: acr-secret, which is used to pull the images from ACR
# 🔐 POD-LEVEL SECURITY (applies to all containers)
securityContext:
runAsNonRoot: true
runAsUser: 1000
containers:
- name: leasetool #The container is named leasetool, can be replaced the required ApplicationName (eg: SCMWebApp..)
image: planvisage.azurecr.io/leasetool:latest #It pulls the latest Leasetool images. Need to replace with respective Image Path.
imagePullPolicy: Always
ports:
- containerPort: 8080 # Exposes port 8080 inside container.
# 🔐 CONTAINER-LEVEL SECURITY
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
capabilities:
drop:
- ALL
env: # Setting Environment Variables
- name: TIME_ZONE
value: "Asia/Kolkata"
- name: DB_CONNECTSTR
value: ""
- name: DB_TYPE
value: ""
- name: BLOB_CONNECTSTR
value: ""
- name: BLOB_CONTAINER_NAME
value: ""
- name: LOG_TARGET
value: "FILE"
- name: SECURE_COOKIE
value: "False" # False since we have not set SSL for the testing, this can be set to True when SSL is setup.
# 📦 VOLUME MOUNTS
# REQUIRED when readOnlyRootFilesystem = true
volumeMounts:
# Writable temp directory (required for read-only root FS)
- name: tmp
mountPath: /tmp
# Writable directory for application logs
- name: applogs
mountPath: /app/wwwroot/log
- name: appconfig
mountPath: /app/wwwroot/xml
- name: appdata
mountPath: /app/wwwroot/data
- name: appdesign
mountPath: /app/wwwroot/design
# 📦 VOLUMES
volumes:
# Logs volume
- name: applogs
emptyDir: {}
# congif volume
- name: appconfig
emptyDir: {}
# data volume
- name: appdata
emptyDir: {}
# design volume
- name: appdesign
emptyDir: {}
# Temp directory
- name: tmp
emptyDir: {}
The environment variables used in the above deployment.yaml (such as database connection strings, blob storage configuration, logging, and security settings) are explained in detail in the document below.
Refer to: Application Environmental Variables
🔹 Optional: Using Azure Key Vault for Sensitive Configuration
This section is optional and should be followed if you wish to setup keyvault to fetch sensitive configuration values such as database connection strings, storage keys, or secrets.
In the basic deployment, sensitive values (e.g., database connection strings) are defined directly in the deployment.yaml file. This approach is not recommended for production environments.
Azure Key Vault provides a secure way to:
-
Store secrets centrally
-
Control access using Managed Identity
-
Avoid hardcoding sensitive data in YAML files
Refer to: How to setup Azure KeyVault for AKS
• In Command Prompt, navigate to the folder containing the YAML files and run:
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl rollout status deployment <kuberneteappname> -n <namespace>
KuberneteAppName refers to the name of the Deployment defined in the deployment.yaml file. In this case, it is set to "leasetool", and the corresponding namespace is "pvtest".
• Check if the pods are running:
kubectl get pods -n <namespace>
EX:
C:\AKSTest>kubectl get pods -n pvtest
NAME READY STATUS RESTARTS AGE
leasetool-7585f58f68-xz5n4 1/1 Running 0 39s
• Check if the service is running:
kubectl get svc <Service Name> -n <Namespace>
EX:
C:\AKSTest>kubectl get svc leasetool-service -n pvtest
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
leasetool-service LoadBalancer 10.0.149.4 4.247.24.42 80:31417/TCP 15s
Copy the External IP displayed by the kubectl get svc command.
- If the service is configured without a private network, open a browser and access the application using:
http://<External-IP>
Ex: http://4.247.24.42/
- If the service is configured for a private network using Application Gateway, the application will not be accessible publicly. In this case, the application can be accessed only from within the same VNET. (To test we can create a VM (Lynux/Windows) in the same VNET and access the app through the externalIP.)
To enable private access using Application Gateway, follow the steps in the section below.