Introduction
Modern software delivery increasingly relies on cloud-native technologies such as containers, Kubernetes, and automated deployment pipelines. This project demonstrates the end-to-end process of building, containerizing, and deploying a .NET 8 Web API to Azure Kubernetes Service (AKS) using industry best practices.
By developing a Weather Forecast API, the project simulates a real-world DevOps workflow where applications are tested locally, packaged with Docker, stored in Azure Container Registry, deployed to Kubernetes, and automatically updated through CI/CD. The goal is to gain practical experience in deploying scalable and production-ready applications in a cloud environment.
Architecture Flow
Prerequisites
Required Software
Install the following tools in this order:
- Visual Studio Code
- .NET 8 SDK
- Git
- Docker Desktop,Start Docker Desktop after installation
- Azure CLI
- kubectl
- GitHub CLI (optional but recommended)
- Required Accounts
- GitHub account (free)
- Azure account (free tier available)
Verify Installations
Run the following commands:
- dotnet --version
- git --version
- docker --version
- az --version
- kubectl version --client
If any command fails, fix it before proceeding.
Step 1: Create and Test the .NET Application Locally
Why This Step Matters
You never deploy untested code.
Testing locally allows you to:
- Catch errors early
- Validate endpoints
- Avoid expensive cloud debugging
1.1 Create Project Structure
Use the command to create directory and to enter into the directory
mkdir weather-app-demo
cd weather-app-demo
mkdir WeatherApp
cd WeatherApp
1.2 Initialize the .NET Web API
dotnet new webapi -minimal
This creates a minimal API with fewer files and faster startup.
1.3 Add Required Packages
This command adds the Health Checks library to your .NET project.
In simple terms:
It installs a package that allows your app to report whether it is healthy or not.
dotnet add package Microsoft.Extensions.Diagnostics.HealthChecks
dotnet add package Swashbuckle.AspNetCore
This installs Swagger support into your .NET Web API project.
Swashbuckle is the library that automatically generates:
- API documentation
- Interactive testing UI In Simple Terms: It gives you a web page where you can see and test all your API endpoints.
Code .
It opens the current folder in Visual Studio Code.
1.4 Replace Program.cs
var builder = WebApplication.CreateBuilder(args);
// Services
builder.Services.AddHealthChecks();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Kestrel config for containers
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenAnyIP(8080);
});
var app = builder.Build();
// Middleware
app.UseSwagger();
app.UseSwaggerUI();
// Endpoints
app.MapGet("/", () => new
{
Message = "Welcome to the Weather App!",
Version = "1.0.0",
Timestamp = DateTime.UtcNow
});
app.MapGet("/weather", () =>
{
var summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool",
"Mild", "Warm", "Hot", "Scorching"
};
return Enumerable.Range(1, 5).Select(i => new
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(i)),
TemperatureC = Random.Shared.Next(-20, 40),
Summary = summaries[Random.Shared.Next(summaries.Length)]
});
});
// Health endpoint for Kubernetes
app.MapHealthChecks("/health");
app.Run();
1.5 Test Locally
dotnet run
Test endpoints:
If this works, your app is ready for containerization.
Step 2: Containerize the Application with Docker
Why Containerize?
Containers ensure:
- Same runtime everywhere
- No “works on my machine” issues
- Smooth Kubernetes deployment
2.1 Create Dockerfile
Use the command touch or New-item Dockerfile
Copy the docker instruction into the dockerfile
# Runtime
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 8080
# Build
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY weatherApp.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish
# Final image
FROM base
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "weatherApp.dll"]
2.2 Create .dockerignore
Use the command touch or New-item .dockerignore
Copy the code into the .dockerignore file.
bin/
obj/
.vs/
.vscode/
.git/
.gitignore
Dockerfile
README.md
*.log
2.3 Build and Test Container Locally
docker build -t weather-app:local .
docker run -p 8080:8080 weather-app:local
Test again in browser or with curl.
If it works locally, it will work in AKS.
Step 3: Create Azure Infrastructure
3.1 Login to Azure
use the command az login or az login --allow-no-subscriptions
once prompted to select a subscription or tenant ID, Click on the ENTER key on your keyboard.
3.2 Create Resource Group
az group create --name student-demo --location eastus
3.3 Create Azure Container Registry (ACR)
3.3.1 Register your subscription to use Microsoft.ContainerRegistry
Use the command to register the service az provider register --namespace Microsoft.ContainerRegistry
and use az provider show --namespace Microsoft.ContainerRegistry --query registrationState to check the registration status.
3.3.2 Create Azure Container Registry (ACR)
Use the command to create Azure Container Registry and give it a Unique name.
az acr create --resource-group student-demo --name studentdemoacr --sku Basic
3.4 Build & Push Image Using ACR
az acr build --registry studentdemoacr --image weather-app:latest . or Instead of using az acr build, you can:
Build locally with Docker and push manually
docker build -t skillstudentdemoacr.azurecr.io/weather-app:latest .
*Login into Azure Container registry *
az acr login --name skillstudentdemoacr
Push image to Azure Container registry
docker push skillstudentdemoacr.azurecr.io/weather-app:latest
3.5 Create AKS Cluster with ACR Attached
Register your subscription to use Microsoft.ContainerService first before creating the AKS cluster.
az provider register --namespace Microsoft.ContainerService
use this to check the status az provider show --namespace Microsoft.ContainerService --query registrationState
Create aks cluster
az aks create --resource-group student-demo --name skillstudent-aks --node-count 1 --attach-acr skillstudentdemoacr --enable-managed-identity --generate-ssh-keys --location eastus
3.6 Connect kubectl to AKS
az aks get-credentials --resource-group student-demo --name student-aks
Verify kubectl get nodes
Step 4: Deploy to Kubernetes
4.1 Create Kubernetes Manifests
Create a directory mkdir k8s
Enter the direwctory cd k8s
Create deployment.yaml file using New-item or touch deployment.yaml
Copy this code into the deployment.yaml file
apiVersion: apps/v1
kind: Deployment
metadata:
name: weather-app
spec:
replicas: 2
selector:
matchLabels:
app: weather-app
template:
metadata:
labels:
app: weather-app
spec:
containers:
- name: weather-app
image: studentdemoacr.azurecr.io/weather-app:latest
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /health
port: 8080
readinessProbe:
httpGet:
path: /health
port: 8080
Create service.yaml file using New-item or touch service.yaml
Copy this code into the service.yaml
apiVersion: v1
kind: Service
metadata:
name: weather-service
spec:
type: LoadBalancer
selector:
app: weather-app
ports:
- port: 80
targetPort: 8080
4.2 Apply Manifests
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
Check status:
kubectl get pods
kubectl get services
Step 5: CI/CD with GitHub Actions
5.1 Initialize Git
git init
git add .
git commit -m "Initial Weather App"
5.2 Create GitHub Repo
*Login to Github *
Use rename your branch to main using git branch -m main
Use git remote add origin https://github.com/Subair-09/WeatherAPP.git to add repository.
Use git push origin main to push the codes to github
5.3 Create Workflow File
Copy and paste this code in the .github/workflows/deploy.yml file
name: CI/CD to AKS
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- run: |
az acr build \
--registry ${{ secrets.ACR_NAME }} \
--image weather-app:${{ github.sha }} .
- run: |
az aks get-credentials \
--resource-group ${{ secrets.RESOURCE_GROUP }} \
--name ${{ secrets.CLUSTER_NAME }}
- run: |
kubectl set image deployment/weather-app \
weather-app=${{ secrets.ACR_NAME }}.azurecr.io/weather-app:${{ github.sha }}
Step 6: Access the Application
kubectl get service weather-service

Use the EXTERNAL-IP in your browser.
Push Github workflow to github
Github action running
Conclusion
This project successfully demonstrates a complete, real-world cloud-native deployment workflow using modern DevOps practices. Starting from local development of a .NET 8 Web API, the application was containerized with Docker, securely stored in Azure Container Registry, and deployed to Azure Kubernetes Service with proper health checks, scalability, and service exposure.
By integrating GitHub Actions for CI/CD, the deployment process was fully automated, ensuring that every change pushed to the repository results in a reliable and repeatable update to the Kubernetes cluster. This mirrors how production systems are built, tested, and delivered in professional cloud environments.
Overall, the project reinforces key concepts such as containerization, Kubernetes orchestration, infrastructure provisioning, and continuous delivery on Azure. It provides a strong foundation for building scalable, resilient, and production-ready applications, and serves as a practical reference for engineers transitioning into cloud and DevOps roles.








































Top comments (0)