<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Siddharth Bhamare</title>
    <description>The latest articles on Forem by Siddharth Bhamare (@siddharth_bhamare_8585).</description>
    <link>https://forem.com/siddharth_bhamare_8585</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2708862%2F81d18133-723d-469b-9935-1977208e9895.png</url>
      <title>Forem: Siddharth Bhamare</title>
      <link>https://forem.com/siddharth_bhamare_8585</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/siddharth_bhamare_8585"/>
    <language>en</language>
    <item>
      <title>End-to-End CI/CD Setup for .NET Microservices on AWS EKS Using Azure DevOps</title>
      <dc:creator>Siddharth Bhamare</dc:creator>
      <pubDate>Fri, 31 Oct 2025 12:27:45 +0000</pubDate>
      <link>https://forem.com/siddharth_bhamare_8585/end-to-end-cicd-setup-for-net-microservices-on-aws-eks-using-azure-devops-1h9d</link>
      <guid>https://forem.com/siddharth_bhamare_8585/end-to-end-cicd-setup-for-net-microservices-on-aws-eks-using-azure-devops-1h9d</guid>
      <description>&lt;p&gt;Create &lt;strong&gt;the ecosystem connections&lt;/strong&gt; between &lt;strong&gt;Azure DevOps&lt;/strong&gt;, &lt;strong&gt;AWS&lt;/strong&gt;, and your &lt;strong&gt;repo&lt;/strong&gt; first, and understand how every piece (Dockerfile, YAML, Kubernetes manifests, etc.) in terms of cloud infrastructure. Understand CI/CD, Cloud compute service EKS, and API Gateway for your microservice (NGINX)&lt;/p&gt;




&lt;h2&gt;
  
  
  Overall Cloud Architecture  (Visual Overview)
&lt;/h2&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg44vypgl3q7kucvya7on.png" alt=" " width="800" height="533"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  🧭 &lt;strong&gt;PART 1 — The Big Picture Flow (Visual Overview)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here’s the end-to-end relationship of files, pipelines, and services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                ┌──────────────────────────────────────────────────┐
                │                 Azure DevOps                     │
                │──────────────────────────────────────────────────│
                │                                                  │
                │ 1️⃣ Build Pipeline (azure-pipelines.yml)          │
Developer Push  │    ↓                                             │
     Code  ────▶│  (uses Dockerfile + dotnet test + code coverage) │
                │    ↓                                             │
                │  Builds Docker image &amp;amp; pushes to AWS ECR         │
                │    ↓                                             │
                │  Publishes artifacts (manifests/templates)       │
                │                                                  │
                │ 2️⃣ Release Pipeline / Deploy Stage               │
                │    ↓                                             │
                │  (takes templates → replaces variables → applies)│
                │    ↓                                             │
                │  kubectl apply to AWS EKS (Kubernetes cluster)   │
                └──────────────────────────────────────────────────┘
                                     │
                                     │  Deploys Container Image
                                     ▼
                 ┌───────────────────────────────────────────┐
                 │                AWS EKS Cluster             │
                 │───────────────────────────────────────────│
                 │ Deployment.yaml → creates Pods             │
                 │ Service.yaml → creates ClusterIP/LoadBalancer │
                 │ ConfigMap/Secrets → inject env vars         │
                 │ Ingress.yaml (NGINX) → exposes API          │
                 └───────────────────────────────────────────┘
                                     │
                                     ▼
                        🌐 Accessible API via Ingress
                          Logs → Application Insights
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧩 &lt;strong&gt;PART 2 — How Files Connect (Step-by-Step Flow)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let’s link each file and configuration together in order:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Step&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;File / Component&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Purpose&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Consumes / Produces&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Dockerfile&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Defines how to build your .NET app into a container.&lt;/td&gt;
&lt;td&gt;Consumed by build pipeline (&lt;code&gt;docker build&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;azure-pipelines.yml&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Your CI/CD automation definition. It: &lt;br&gt; - Builds app &lt;br&gt; - Runs tests + coverage &lt;br&gt; - Builds Docker image &lt;br&gt; - Pushes image to AWS ECR &lt;br&gt; - Deploys manifests to AWS EKS&lt;/td&gt;
&lt;td&gt;Consumes: Dockerfile, test project, manifests. &lt;br&gt; Produces: Docker image in ECR, deployment in EKS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;configmap.template.yaml / secrets.template.yaml&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Define environment variables (non-sensitive in ConfigMap, sensitive in Secret).&lt;/td&gt;
&lt;td&gt;Consumed by Deploy stage. Gets substituted and applied to Kubernetes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;deployment.yaml.template&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Defines how many Pods to run, which image to use, and what ConfigMap/Secret to pull.&lt;/td&gt;
&lt;td&gt;Consumed by Deploy stage. Gets image tag replaced and applied to EKS.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;service.yaml&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Exposes your app internally (ClusterIP / LoadBalancer).&lt;/td&gt;
&lt;td&gt;Linked to Deployment via label selectors.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ingress.yaml&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Exposes app to the public through NGINX Ingress Controller.&lt;/td&gt;
&lt;td&gt;Linked to Service. Controls routing and domain mapping.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;App Insights config (via environment variable)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Captures logs from the app and sends to Azure.&lt;/td&gt;
&lt;td&gt;Linked via Secret/ConfigMap and Serilog in code.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  ⚙️ &lt;strong&gt;PART 3 — What to Set Up First (Foundation Setup Order)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here’s the &lt;em&gt;correct first-time setup order&lt;/em&gt; for Azure DevOps ↔ AWS ↔ Repo.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧩 &lt;strong&gt;Step 1: Setup AWS Resources&lt;/strong&gt;
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Resource&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ECR (Elastic Container Registry)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Create a repo (e.g., &lt;code&gt;myservice&lt;/code&gt;).&lt;/td&gt;
&lt;td&gt;Stores your Docker images built by Azure DevOps.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;EKS (Elastic Kubernetes Service)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Create a cluster (via &lt;code&gt;eksctl&lt;/code&gt; or AWS Console).&lt;/td&gt;
&lt;td&gt;This will host your deployed containers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IAM User/Role for Azure DevOps&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Create an IAM user with permissions for ECR (push/pull) and EKS (read/write). Generate Access Key + Secret Key.&lt;/td&gt;
&lt;td&gt;Used by Azure DevOps to authenticate with AWS.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;✅ &lt;em&gt;Tip:&lt;/em&gt; Attach AWS managed policies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AmazonECRFullAccess&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AmazonEKSClusterPolicy&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AmazonEKSWorkerNodePolicy&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AmazonEKS_CNI_Policy&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AmazonEC2ContainerRegistryPowerUser&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🧩 &lt;strong&gt;Step 2: Setup Azure DevOps Project&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://dev.azure.com" rel="noopener noreferrer"&gt;dev.azure.com&lt;/a&gt; → create &lt;strong&gt;Project&lt;/strong&gt; (e.g., &lt;code&gt;MyServiceProject&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Create a &lt;strong&gt;Service Connection&lt;/strong&gt; for AWS:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Project Settings → Service connections → New → AWS.&lt;/li&gt;
&lt;li&gt;Enter Access Key, Secret Key from Step 1, Region.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Name it e.g., &lt;code&gt;AWS-Prod-Connection&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create &lt;strong&gt;Pipeline&lt;/strong&gt;:&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go to Pipelines → New → Import &lt;code&gt;azure-pipelines.yml&lt;/code&gt; from your repo root.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create &lt;strong&gt;Environment Variables / Pipeline Variables&lt;/strong&gt;:&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;APP_ENV&lt;/code&gt;, &lt;code&gt;DB_CONN&lt;/code&gt;, &lt;code&gt;FEATURE_FLAG_X&lt;/code&gt;, etc.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create &lt;strong&gt;Variable Groups&lt;/strong&gt; (optional) for environment-specific settings.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🧩 &lt;strong&gt;Step 3: Setup Repo and Link to Azure DevOps&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Push your repo (code + pipeline + k8s templates) to Azure DevOps Repos or GitHub.&lt;/li&gt;
&lt;li&gt;Ensure your pipeline YAML file is at repo root.&lt;/li&gt;
&lt;li&gt;In Azure DevOps → Pipeline → Create pipeline → Choose “Existing Azure Pipelines YAML file”.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  🧩 &lt;strong&gt;Step 4: Setup Kubernetes Connectivity&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Inside Azure DevOps pipeline, we run commands like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws eks update-kubeconfig &lt;span class="nt"&gt;--region&lt;/span&gt; &amp;lt;region&amp;gt; &lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;EKS_CLUSTER_NAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔑 This works only if your &lt;strong&gt;AWS Service Connection&lt;/strong&gt; user has EKS cluster permissions.&lt;/p&gt;

&lt;p&gt;You can test connectivity manually on your local machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws eks update-kubeconfig &lt;span class="nt"&gt;--region&lt;/span&gt; &amp;lt;region&amp;gt; &lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;EKS_CLUSTER_NAME&amp;gt;
kubectl get nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it works locally, it’ll work inside the pipeline.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧩 &lt;strong&gt;Step 5: Setup NGINX Ingress Controller&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Once the EKS cluster is ready:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm &lt;span class="nb"&gt;install &lt;/span&gt;ingress-nginx ingress-nginx/ingress-nginx &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; ingress-nginx &lt;span class="nt"&gt;--create-namespace&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’ll deploy the NGINX ingress controller.&lt;br&gt;
Then your &lt;code&gt;ingress.yaml&lt;/code&gt; connects external traffic to your app’s &lt;code&gt;service.yaml&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧩 &lt;strong&gt;Step 6: Setup Application Insights (Azure Portal)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;In Azure Portal → Create a &lt;strong&gt;Log Analytics workspace&lt;/strong&gt; + &lt;strong&gt;Application Insights&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Copy its &lt;strong&gt;Connection String&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add that value as a &lt;strong&gt;Kubernetes Secret&lt;/strong&gt; or pipeline variable (to inject during deployment):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   APPINSIGHTS_CONNECTIONSTRING="InstrumentationKey=..."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Your &lt;code&gt;.NET&lt;/code&gt; app automatically starts sending logs once deployed.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  🧩 &lt;strong&gt;Step 7: Run the Full Flow&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;✅ Push code to main → Build pipeline triggers →&lt;br&gt;
✅ Docker image built + pushed to ECR →&lt;br&gt;
✅ Deploy stage runs →&lt;br&gt;
✅ &lt;code&gt;kubectl apply&lt;/code&gt; updates EKS →&lt;br&gt;
✅ NGINX Ingress exposes service →&lt;br&gt;
✅ Application logs flow to AppInsights.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔁 &lt;strong&gt;Understanding Template Variables&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let’s clarify what to replace in your &lt;code&gt;.template&lt;/code&gt; files:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Placeholder&lt;/th&gt;
&lt;th&gt;Replace With&lt;/th&gt;
&lt;th&gt;Comes From&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;__IMAGE__&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;AWS_ACCOUNT_ID&amp;gt;.dkr.ecr.&amp;lt;region&amp;gt;.amazonaws.com/myservice:&amp;lt;Build.BuildId&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build pipeline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;__APP_ENV__&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Production&lt;/code&gt; / &lt;code&gt;Staging&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Pipeline variable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;__FEATURE_FLAG_X__&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true/false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pipeline variable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;__DB_CONN__&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PostgreSQL connection string (from AWS RDS / Secrets Manager)&lt;/td&gt;
&lt;td&gt;Pipeline variable / Secret&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;__APPINSIGHTS_CONNECTIONSTRING__&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Value from Azure Application Insights&lt;/td&gt;
&lt;td&gt;Secret&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;__EKS_CLUSTER_NAME__&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your EKS cluster name&lt;/td&gt;
&lt;td&gt;AWS Console&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🧩 &lt;strong&gt;BONUS — Suggested First-Time Order of Execution&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Where&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Create AWS ECR repo&lt;/td&gt;
&lt;td&gt;AWS Console&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Create AWS EKS cluster&lt;/td&gt;
&lt;td&gt;AWS Console / eksctl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Setup IAM User with ECR/EKS permissions&lt;/td&gt;
&lt;td&gt;AWS IAM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Setup Azure DevOps Project + AWS Service Connection&lt;/td&gt;
&lt;td&gt;Azure DevOps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Push repo (code + Dockerfile + pipeline YAML + k8s templates)&lt;/td&gt;
&lt;td&gt;Git&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Create pipeline (YAML) and run once manually&lt;/td&gt;
&lt;td&gt;Azure DevOps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Verify ECR image pushed&lt;/td&gt;
&lt;td&gt;AWS Console&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Verify EKS deployment created via &lt;code&gt;kubectl get pods&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Local or DevOps log&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;Install NGINX ingress, create ingress.yaml&lt;/td&gt;
&lt;td&gt;AWS EKS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Add Application Insights connection string &amp;amp; verify logs&lt;/td&gt;
&lt;td&gt;Azure Portal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>azure</category>
      <category>devops</category>
      <category>kubernetes</category>
      <category>aws</category>
    </item>
    <item>
      <title>Day 4 - 🔐 Securing API with Keycloak</title>
      <dc:creator>Siddharth Bhamare</dc:creator>
      <pubDate>Fri, 05 Sep 2025 13:23:02 +0000</pubDate>
      <link>https://forem.com/siddharth_bhamare_8585/day-4-securing-api-with-keycloak-53gd</link>
      <guid>https://forem.com/siddharth_bhamare_8585/day-4-securing-api-with-keycloak-53gd</guid>
      <description>&lt;p&gt;&lt;em&gt;If you already have a .NET API running, you can integrate Keycloak to provide authentication and role-based authorization without rewriting your backend. This guide covers setup, token handling, role-based policies, and common questions.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Keycloak?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Keycloak is an open-source identity and access management (IAM) solution. It helps developers secure applications and services with minimal effort. Keycloak provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single Sign-On (SSO): Users log in once to access multiple apps.&lt;/li&gt;
&lt;li&gt;User Management: Create, update, and delete users via admin console or API.&lt;/li&gt;
&lt;li&gt;Role-Based Access Control (RBAC): Assign roles to users to restrict access to specific resources.&lt;/li&gt;
&lt;li&gt;Support for Multiple Protocols: OpenID Connect, OAuth2, SAML.&lt;/li&gt;
&lt;li&gt;Integration with Multiple Platforms: Works with Java, .NET, Node.js, and more.&lt;/li&gt;
&lt;li&gt;Keycloak removes the need to implement authentication and authorization logic in your application, making it ideal for both development and production environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why Keycloak?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even if you are using IdentityServer (Duende), Keycloak provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ready-to-use IAM server with UI and SSO.&lt;/li&gt;
&lt;li&gt;Role management and RBAC to secure endpoints easily.&lt;/li&gt;
&lt;li&gt;Open-source and production-ready with clustering and Kubernetes support.&lt;/li&gt;
&lt;li&gt;Supports multiple protocols for future integrations (mobile, frontend, microservices).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When to choose Keycloak:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Centralized authentication across multiple services.&lt;/li&gt;
&lt;li&gt;Admin UI to manage users, roles, and clients.&lt;/li&gt;
&lt;li&gt;Plan to implement SSO for frontend apps or mobile apps.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Pull Request Example&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/SiddharthBhamare/SmartKart-Catalog/pull/4" rel="noopener noreferrer"&gt;Git Hub Pull Requests&lt;/a&gt;
demonstrates:&lt;/li&gt;
&lt;li&gt;JWT authentication in an existing API&lt;/li&gt;
&lt;li&gt;Role-based authorization (admin and vendor)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  - Minimal changes to existing controllers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Setting Up Keycloak (Docker)&lt;/strong&gt;&lt;br&gt;
The easiest way to try Keycloak locally is via Docker.&lt;br&gt;
&lt;em&gt;&lt;strong&gt;Official Guide:&lt;/strong&gt;&lt;/em&gt; &lt;a href="https://www.keycloak.org/getting-started/getting-started-docker" rel="noopener noreferrer"&gt;Keycloak Docker Getting Started&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d \
  --name keycloak \
  -p 8080:8080 \
  -e KEYCLOAK_ADMIN=admin \
  -e KEYCLOAK_ADMIN_PASSWORD=admin \
  quay.io/keycloak/keycloak:25.0.6 start-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Access the admin console: &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Username: admin&lt;/li&gt;
&lt;li&gt;Password: admin&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Keycloak Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a Realm: demo-realm&lt;/li&gt;
&lt;li&gt;Create a Client for Your API:&lt;/li&gt;
&lt;li&gt;Client ID: demo-api&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Protocol: OpenID Connect&lt;/li&gt;
&lt;li&gt;Access Type: confidential&lt;/li&gt;
&lt;li&gt;Copy the Client Secret&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Create Roles:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;admin&lt;/li&gt;
&lt;li&gt;vendor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Create Users and Assign Roles:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example: admin-user → assign admin&lt;/li&gt;
&lt;li&gt;Example: vendor-user → assign vendor&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Securing Your Existing .NET API&lt;/strong&gt;&lt;br&gt;
Assuming your API is already created, you only need to add authentication and authorization.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Microsoft.AspNetCore.Authentication.JwtBearer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update Program.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var builder = WebApplication.CreateBuilder(args);

// Authentication
builder.Services.AddAuthentication("Bearer")
    .AddJwtBearer("Bearer", options =&amp;gt;
    {
        options.Authority = "http://localhost:8080/realms/demo-realm";
        options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
        {
            ValidateAudience = true,
            ValidAudience = "demo-api"
        };
    });

// Authorization policies
builder.Services.AddAuthorization(options =&amp;gt;
{
    options.AddPolicy("AdminOnly", policy =&amp;gt; policy.RequireRole("admin"));
    options.AddPolicy("VendorOnly", policy =&amp;gt; policy.RequireRole("vendor"));
    options.AddPolicy("AdminOrVendor", policy =&amp;gt; policy.RequireRole("admin", "vendor"));
});

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();
app.MapControllers(); // Existing API controllers
app.Run();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Applying Role-Based Access in Controllers&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Authorize(Roles = "admin")]
[Route("api/[controller]")]
public class AdminController : ControllerBase
{
    [HttpGet("dashboard")]
    public IActionResult GetAdminData() =&amp;gt; Ok("Hello Admin 👑");
}

[Authorize(Roles = "vendor")]
[Route("api/[controller]")]
public class VendorController : ControllerBase
{
    [HttpGet("dashboard")]
    public IActionResult GetVendorData() =&amp;gt; Ok("Hello Vendor 🛍️");
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Getting an Access Token&lt;br&gt;
Using cURL [use powershell] - Update your url, username, password and client id&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl.exe --insecure -X POST "http://localhost:8080/realms/demo-realm/protocol/openid-connect/token" `
&amp;gt;&amp;gt; -H "Content-Type: application/x-www-form-urlencoded" `
&amp;gt;&amp;gt; -d "grant_type=password&amp;amp;client_id=demo-api&amp;amp;client_secret=&amp;lt;client-secret&amp;gt;&amp;amp;username=yourusername&amp;amp;password=yourpassword"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Authority vs ValidIssuer&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authority: Base URL of Keycloak (&lt;a href="http://localhost:8080/realms/demo-realm" rel="noopener noreferrer"&gt;http://localhost:8080/realms/demo-realm&lt;/a&gt;). Middleware fetches metadata automatically.&lt;/li&gt;
&lt;li&gt;ValidIssuer: Exact iss claim from token. Usually not required unless running behind reverse proxies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Best Practice: Use Authority + ValidAudience. Only override ValidIssuer if needed.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Common Doubts/Questions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Why Keycloak over IdentityServer?&lt;/strong&gt;&lt;br&gt;
Keycloak is ready-to-use with UI, SSO, and role management; IdentityServer requires more custom coding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Can multiple APIs share one realm?&lt;/strong&gt;&lt;br&gt;
Yes, each API can have its own client in Keycloak.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- How are roles assigned?&lt;/strong&gt;&lt;br&gt;
Realm roles = global, Client roles = API-specific, users can have multiple roles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Is Keycloak production-ready?&lt;/strong&gt;&lt;br&gt;
Yes, supports clustering, load-balancing, and Kubernetes deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Can I do client-to-client authentication?&lt;/strong&gt;&lt;br&gt;
Yes, using the client credentials grant type.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Keycloak Docker Guide: &lt;a href="https://www.keycloak.org/getting-started/getting-started-docker" rel="noopener noreferrer"&gt;https://www.keycloak.org/getting-started/getting-started-docker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub PR: SmartKart-Catalog #4 &lt;a href="https://github.com/SiddharthBhamare/SmartKart-Catalog/pull/4" rel="noopener noreferrer"&gt;https://github.com/SiddharthBhamare/SmartKart-Catalog/pull/4&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>dotnetcore</category>
      <category>programming</category>
    </item>
    <item>
      <title>🚀 Day 3: Architectures Explained with My Implementation</title>
      <dc:creator>Siddharth Bhamare</dc:creator>
      <pubDate>Sun, 24 Aug 2025 15:23:59 +0000</pubDate>
      <link>https://forem.com/siddharth_bhamare_8585/day-3-architectures-explained-with-my-implementation-2pd0</link>
      <guid>https://forem.com/siddharth_bhamare_8585/day-3-architectures-explained-with-my-implementation-2pd0</guid>
      <description>&lt;p&gt;&lt;em&gt;(DDD + Clean + Onion + Microservices)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Many times in interviews, questions come like:&lt;br&gt;
👉 “What’s the difference between DDD, Clean, and Onion Architecture?”&lt;br&gt;
👉 “How do you apply them in a real project?”&lt;br&gt;
👉 “Why Microservices over Monolith?”&lt;/p&gt;

&lt;p&gt;Today, I’ll simplify these with my &lt;strong&gt;Catalog Service&lt;/strong&gt; example (Products, Categories, Brands).&lt;/p&gt;




&lt;h2&gt;
  
  
  1️⃣ Domain-Driven Design (DDD)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Focuses on the &lt;strong&gt;Domain Model&lt;/strong&gt; (business rules, not just CRUD).&lt;/li&gt;
&lt;li&gt;Uses &lt;strong&gt;Entities, Value Objects, Repositories, Aggregates, Aggregate Roots&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Communication happens via &lt;strong&gt;Ubiquitous Language&lt;/strong&gt; (same words as business).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Layers in DDD:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Domain Layer (Inner)&lt;/strong&gt; → Entities (&lt;code&gt;Product&lt;/code&gt;, &lt;code&gt;Category&lt;/code&gt;), Interfaces (&lt;code&gt;IProductRepository&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application Layer (Middle)&lt;/strong&gt; → Services (&lt;code&gt;ProductService&lt;/code&gt; orchestrating use cases).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure Layer (Outer)&lt;/strong&gt; → EF Core, DB, external APIs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;My Example:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Product&lt;/code&gt; is an &lt;strong&gt;Aggregate Root&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;IProductRepository&lt;/code&gt; ensures access through the domain contract.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;EfRepository&amp;lt;Product&amp;gt;&lt;/code&gt; (Infra) implements &lt;code&gt;IProductRepository&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Application Layer (&lt;code&gt;ProductService&lt;/code&gt;) coordinates actions like “Add Product to Category.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Interview Tip: DDD ensures &lt;strong&gt;business-first design&lt;/strong&gt;, avoids anemic models.&lt;/p&gt;




&lt;h2&gt;
  
  
  2️⃣ Clean Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Robert C. Martin (Uncle Bob) → emphasis on &lt;strong&gt;independence&lt;/strong&gt; of frameworks, UI, DB.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency Rule:&lt;/strong&gt; All dependencies point &lt;strong&gt;inward&lt;/strong&gt;, towards the &lt;strong&gt;Domain&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Layers (from inner to outer):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Entities (Domain)&lt;/strong&gt; → Business rules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Cases (Application)&lt;/strong&gt; → Application-specific business logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interface Adapters&lt;/strong&gt; → Controllers, Presenters, DTOs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frameworks &amp;amp; Drivers (Outer)&lt;/strong&gt; → EF Core, ASP.NET Core, DB, external systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;My Example:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Entities&lt;/strong&gt;: &lt;code&gt;Product&lt;/code&gt;, &lt;code&gt;Category&lt;/code&gt;, &lt;code&gt;Brand&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Cases&lt;/strong&gt;: &lt;code&gt;ProductService&lt;/code&gt;, &lt;code&gt;CategoryService&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interface Adapters&lt;/strong&gt;: ASP.NET Core Controllers (&lt;code&gt;ProductController&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frameworks/Drivers&lt;/strong&gt;: &lt;code&gt;CatalogDbContext&lt;/code&gt;, EF Core repositories.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Interview Tip: Clean Architecture is &lt;strong&gt;technology-agnostic&lt;/strong&gt; → I can switch from EF Core to Dapper without touching Domain/Application.&lt;/p&gt;




&lt;h2&gt;
  
  
  3️⃣ Onion Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Similar to Clean, but visually represented as &lt;strong&gt;onion rings&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inner Core = Domain&lt;/strong&gt;, outer layers depend on inner.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Layers (from core out):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Core (Domain)&lt;/strong&gt; → Entities (&lt;code&gt;Product&lt;/code&gt;, &lt;code&gt;Category&lt;/code&gt;), Interfaces (&lt;code&gt;IRepository&amp;lt;T&amp;gt;&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application Layer&lt;/strong&gt; → Services (&lt;code&gt;ProductService&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure Layer&lt;/strong&gt; → Repositories (&lt;code&gt;EfRepository&amp;lt;Product&amp;gt;&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Presentation Layer&lt;/strong&gt; → API Controllers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;My Example:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inner Onion Ring = &lt;code&gt;Product&lt;/code&gt; + &lt;code&gt;IProductRepository&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Middle = &lt;code&gt;ProductService&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Outer = &lt;code&gt;EfRepository&amp;lt;Product&amp;gt;&lt;/code&gt; + &lt;code&gt;ProductController&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Interview Tip: Onion vs Clean = philosophy is same (&lt;strong&gt;dependency direction&lt;/strong&gt;). Onion is more &lt;strong&gt;visual metaphor&lt;/strong&gt;, Clean is more &lt;strong&gt;principle-driven&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  4️⃣ Microservices
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Break monolith into &lt;strong&gt;independent services&lt;/strong&gt; around business capabilities.&lt;/li&gt;
&lt;li&gt;Each service has its own &lt;strong&gt;DB + bounded context&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;My Example:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Catalog Service&lt;/strong&gt; = Products, Categories, Brands.&lt;/li&gt;
&lt;li&gt;Future &lt;strong&gt;Order Service&lt;/strong&gt; = Orders, Payments.&lt;/li&gt;
&lt;li&gt;Communication → REST / gRPC / Messaging (RabbitMQ, Kafka).&lt;/li&gt;
&lt;li&gt;Independent DBs → CatalogDB, OrderDB.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Interview Tip: Microservices solve &lt;strong&gt;scaling + team autonomy&lt;/strong&gt;, but add &lt;strong&gt;complexity (distributed systems)&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 How They All Connect in My Project
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DDD&lt;/strong&gt; → defines my &lt;strong&gt;Domain &amp;amp; Repositories&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean Architecture&lt;/strong&gt; → ensures &lt;strong&gt;dependency flow&lt;/strong&gt; is inward.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Onion Architecture&lt;/strong&gt; → shows &lt;strong&gt;layered structure&lt;/strong&gt; visually.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microservices&lt;/strong&gt; → breaks &lt;strong&gt;Catalog, Order, Auth&lt;/strong&gt; into separate deployable units.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;✅ So when interviewers ask &lt;em&gt;“Which architecture are you following?”&lt;/em&gt; → My answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I use a combination of &lt;strong&gt;DDD for domain modeling&lt;/strong&gt;, &lt;strong&gt;Onion/Clean for dependency flow&lt;/strong&gt;, and &lt;strong&gt;Microservices for scalability and independence&lt;/strong&gt;. For example, in my Catalog Service, &lt;code&gt;Product&lt;/code&gt; is an Aggregate Root in the Domain Layer, &lt;code&gt;EfRepository&amp;lt;Product&amp;gt;&lt;/code&gt; sits in Infrastructure, &lt;code&gt;ProductService&lt;/code&gt; in Application, and ASP.NET Controllers in the Presentation Layer. This separation ensures testability, maintainability, and future scalability.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;📌 GitHub repo &lt;a href="https://github.com/SiddharthBhamare/SmartKart-Catalog.git" rel="noopener noreferrer"&gt;https://github.com/SiddharthBhamare/SmartKart-Catalog.git&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stay tuned! 🚀&lt;/p&gt;

&lt;h1&gt;
  
  
  dotnet #architecture #ddd #cleanarchitecture #microservices #onionarchitecture #softwareengineering
&lt;/h1&gt;

</description>
    </item>
    <item>
      <title>🔐 SmartKart Microservices Series Day 2</title>
      <dc:creator>Siddharth Bhamare</dc:creator>
      <pubDate>Sat, 26 Jul 2025 13:13:04 +0000</pubDate>
      <link>https://forem.com/siddharth_bhamare_8585/smartkart-microservices-series-4ob6</link>
      <guid>https://forem.com/siddharth_bhamare_8585/smartkart-microservices-series-4ob6</guid>
      <description>&lt;h2&gt;
  
  
  🧭 Day 2: Kicking off Auth Service – Exploring Keycloak vs. Duende IdentityServer
&lt;/h2&gt;

&lt;p&gt;In our journey to build a robust, secure, and scalable e-commerce platform (SmartKart 🛒) using &lt;strong&gt;.NET Core and Microservices&lt;/strong&gt;, we are now diving into the &lt;strong&gt;Authentication and Authorization&lt;/strong&gt; layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Start With AuthService?&lt;/strong&gt;&lt;br&gt;
Authentication is a cross-cutting concern and a foundational piece for secure APIs. Starting here ensures all downstream services follow a consistent security model.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;🔍 What is Keycloak (in simple words)?&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Keycloak&lt;/strong&gt; is an &lt;strong&gt;open-source identity and access management tool&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think of it as a &lt;strong&gt;central place&lt;/strong&gt; where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users register and log in 🔑&lt;/li&gt;
&lt;li&gt;Roles and permissions are managed 🛡️&lt;/li&gt;
&lt;li&gt;Tokens (JWT) are issued for secure API access 🧾&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the best part? It already has all the features built-in — &lt;strong&gt;you don’t have to code login pages, password management, token handling, etc., yourself!&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;✅ &lt;strong&gt;Why We Chose Keycloak Over Other Options&lt;/strong&gt;&lt;br&gt;
As a .NET Core engineer, I evaluated a few options like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ASP.NET Identity + JWT (custom)&lt;/li&gt;
&lt;li&gt;Duende IdentityServer (formerly IdentityServer4)&lt;/li&gt;
&lt;li&gt;Keycloak&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's why I picked Keycloak:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✔️ 1. Fully Open Source&lt;/strong&gt;&lt;br&gt;
No license needed for commercial use. Duende requires a paid license for most real-world projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✔️ 2. Feature-Rich, Out of the Box&lt;/strong&gt;&lt;br&gt;
Login UI, forgot password, role mapping, token issuance — all ready without writing extra code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✔️ 3. Centralized User Management&lt;/strong&gt;&lt;br&gt;
You get a user-friendly admin panel to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add/edit users&lt;/li&gt;
&lt;li&gt;Assign roles&lt;/li&gt;
&lt;li&gt;Configure clients/apps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✔️ 4. Standards-Based Protocols&lt;/strong&gt;&lt;br&gt;
Supports OAuth2.0, OpenID Connect, and even SAML — works well with .NET Core's JWT middleware.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✔️ 5. Easy to Integrate with .NET Core&lt;/strong&gt;&lt;br&gt;
Though written in Java, it’s protocol-based, so integration with .NET Core is seamless using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JWT Bearer Authentication&lt;/li&gt;
&lt;li&gt;OpenID Connect client libraries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✔️ 6. Scalable &amp;amp; Cloud-Friendly&lt;/strong&gt;&lt;br&gt;
Supports Docker, Kubernetes, and clustering — ideal for microservices.&lt;/p&gt;




&lt;p&gt;📌 &lt;strong&gt;Summary Comparison Table :&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Keycloak ✅&lt;/th&gt;
&lt;th&gt;Duende IdentityServer ❌&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Open Source (free to use)&lt;/td&gt;
&lt;td&gt;✔️ Yes&lt;/td&gt;
&lt;td&gt;❌ No (requires paid license)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Admin UI for users/roles&lt;/td&gt;
&lt;td&gt;✔️ Built-in&lt;/td&gt;
&lt;td&gt;❌ Needs custom development&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Login/Register/Forgot UI&lt;/td&gt;
&lt;td&gt;✔️ Provided&lt;/td&gt;
&lt;td&gt;❌ Build yourself&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Protocol Support (OAuth2/OIDC)&lt;/td&gt;
&lt;td&gt;✔️ Yes&lt;/td&gt;
&lt;td&gt;✔️ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easy .NET Core Integration&lt;/td&gt;
&lt;td&gt;✔️ Yes (via JWT/OIDC)&lt;/td&gt;
&lt;td&gt;✔️ Native&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-tenant support&lt;/td&gt;
&lt;td&gt;✔️ Realms&lt;/td&gt;
&lt;td&gt;❌ Manual effort&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
    </item>
    <item>
      <title>🚀 SmartKart Microservices Series – Day 1: Architecture &amp; Flow</title>
      <dc:creator>Siddharth Bhamare</dc:creator>
      <pubDate>Fri, 25 Jul 2025 17:02:35 +0000</pubDate>
      <link>https://forem.com/siddharth_bhamare_8585/smartkart-microservices-series-day-1-architecture-flow-5o3</link>
      <guid>https://forem.com/siddharth_bhamare_8585/smartkart-microservices-series-day-1-architecture-flow-5o3</guid>
      <description>&lt;p&gt;🔷 &lt;strong&gt;Welcome to Day 1 of my Full-Stack Learning Challenge!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Over the next few weeks, I’ll be building &lt;strong&gt;SmartKart&lt;/strong&gt;, a complete E-Commerce system using cutting-edge technologies and principles. This series will not only help me learn but also share back insights with the community 💡&lt;/p&gt;




&lt;p&gt;🧠 &lt;strong&gt;Why SmartKart?&lt;/strong&gt;&lt;br&gt;
As a backend engineer, I wanted a project that showcases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microservices using .NET 8, Clean Architecture, and DDD&lt;/li&gt;
&lt;li&gt;API Gateway, Service Discovery, and Message Brokering with RabbitMQ&lt;/li&gt;
&lt;li&gt;Caching with Redis&lt;/li&gt;
&lt;li&gt;Full-text search using Elasticsearch&lt;/li&gt;
&lt;li&gt;Secure Auth with JWT, OAuth2, and OpenID Connect&lt;/li&gt;
&lt;li&gt;ORM with EF Core, performance boosts with Dapper&lt;/li&gt;
&lt;li&gt;Future-ready: scalable frontend in React/React Native + Docker CI/CD&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;🏗️ &lt;strong&gt;Architecture Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe2gd78afxb0hjngnmi3y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe2gd78afxb0hjngnmi3y.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔹&lt;strong&gt;API Gateway&lt;/strong&gt;&lt;br&gt;
Acts as the single entry point, handling routing, authentication, rate limiting, etc.&lt;/p&gt;

&lt;p&gt;🔹 &lt;strong&gt;Auth Service&lt;/strong&gt;&lt;br&gt;
Implements IdentityServer/OpenID for user login, registration, and token issuance.&lt;/p&gt;

&lt;p&gt;🔹 &lt;strong&gt;Product, Order, Cart, and Payment Services&lt;/strong&gt;&lt;br&gt;
Each built as isolated microservices with their own DB, following Clean Architecture and DDD.&lt;/p&gt;

&lt;p&gt;🔹&lt;strong&gt;Event Bus (RabbitMQ)&lt;/strong&gt;&lt;br&gt;
Enables asynchronous communication between services for tasks like inventory update, order placed, etc.&lt;/p&gt;

&lt;p&gt;🔹 &lt;strong&gt;Redis&lt;/strong&gt;&lt;br&gt;
Used for caching product data and session tokens to boost performance.&lt;/p&gt;

&lt;p&gt;🔹 &lt;strong&gt;Elasticsearch&lt;/strong&gt;&lt;br&gt;
For blazing-fast search experience in products and orders.&lt;/p&gt;

&lt;p&gt;🔹 &lt;strong&gt;Service Registry (Consul/equivalent)&lt;/strong&gt;&lt;br&gt;
Enables service discovery for scalable deployment.&lt;/p&gt;

&lt;p&gt;🔹 &lt;strong&gt;Database&lt;/strong&gt;&lt;br&gt;
Each service uses its own DB (PostgreSQL or SQL Server), connected via EF Core, and selectively using Dapper where performance is critical.&lt;/p&gt;

&lt;p&gt;🔹 &lt;strong&gt;Dockerized Setup&lt;/strong&gt;&lt;br&gt;
All services will run locally in Docker containers to ensure production-like behavior without cloud dependency.&lt;/p&gt;




&lt;p&gt;🗺️ &lt;strong&gt;Request Flow (Example)&lt;/strong&gt;&lt;br&gt;
1️⃣ A user logs in → Auth Service returns a JWT&lt;br&gt;
2️⃣ API Gateway validates JWT and routes request to Product Service&lt;br&gt;
3️⃣ Product Service fetches data (from DB or Redis), returns to Gateway&lt;br&gt;
4️⃣ User adds product to cart → Cart Service updates DB and emits event to RabbitMQ&lt;br&gt;
5️⃣ Order Service consumes the event and updates the order pipeline&lt;br&gt;
6️⃣ All updates are searchable via Elasticsearch!&lt;/p&gt;

</description>
      <category>smartkartbysiddharth</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
