← Back to list

3-Tier Azure IaaS : MERN Bookstore (Part 1) | Network Foundation, VNet, Subnets, NSGs, Bastion, NAT…

I’m a self-taught engineer. No CS degree, no corporate IT background. What I do have is a homelab with four physical machines, a few years…

TANISH GUPTE · 2026-08-11 19:44 · 0 claps · 4.1 min read
#3-tier-architecture #nat-gateway #azure-bastion #network-security-group
Open on Medium ↗
Wiki topics: ☁️ · DevOps & Cloud 🏛️ · Architecture

3-Tier Azure IaaS : MERN Bookstore (Part 1) | Network Foundation, VNet, Subnets, NSGs, Bastion, NAT Gateway

I’m a self-taught engineer. No CS degree, no corporate IT background. What I do have is a homelab with four physical machines, a few years of building Node.js backends, and an obsessive need to understand how systems work from the bottom up.

Earlier this year, I documented a distributed MERN system across four physical LAN machines | Nginx TLS termination, round-robin load balancing, systemd-managed Node.js backends, and a centralised Prometheus + Grafana observability stack. That project taught me a lot about networking and infrastructure at a fundamental level. But physical machines have a ceiling. You can’t add four more when traffic spikes at 2 AM. You can’t deprovision a machine in thirty seconds to stop paying for it.

So I moved to Azure. This article documents what I built, in what order, why each decision was made, and critically the mistakes I made that I want to avoid the next time.

Services overview :

  • Resource Groups => housing all the resources including our VNET
  • Vnets => Subnets
  • VM’s => VMSS
  • NSG’s per subnet
  • Bastion => secure VM ssh access without public IP
  • Cosmosdb (Store Mongodb data)
  • Storage Account => host application’s frontend/backend code ZIP’s
  • NAT Gateway => secure outbound access to the VM’s with pvt IP
  • Pvt endpoint for CosmosDB
  • UAMI =>VMs authenticate to Azure services without passwords
  • Key Vault => stores the CosmosDB connection string
  • VM Images for VMSS creation
  • Azure Compute Gallery => Storing VM images
  • Application Gateway (L7)
  • Internal Load Balancer (L4)
  • Azure Monitor => metric alerts and Log Analytics for observability

Architecture Overview :

Internet (HTTPS/HTTP) => Application Gateway (public IP, snet-agw, Standard V2) [TLS termination, Layer 7 routing, health probes] => Web VMSS (Nginx, snet-web, 2–4 instances) [serves React frontend, proxies /api/* to ILB] => Internal Load Balancer (private IP: 10.0.2.4, snet-app) => [Layer 4, round-robin, health probes on /api/health] => App VMSS (Node.js, snet-app, 2–6 instances) [reads code from Blob, secrets from Key Vault on every boot] => CosmosDB (MongoDB API, Serverless) [behind private endpoint, never reachable from internet]

Everything runs inside a single VNet (10.0.0.0/16) in Central India. The only public IP in the entire architecture is on the Application Gateway. Every other resource is private. The database is reachable only through a private endpoint, which means even if someone stole my CosmosDB connection string, they couldn’t connect to it from outside the VNet.

  • snet-agw-bookstore-cent-ind : 10.0.0.0/24 => Application Gateway (dedicated, mandatory)
  • snet-web-bookstore-cent-ind : 10.0.1.0/24 => Web VMSS (Nginx)
  • snet-app-bookstore-cent-ind : 10.0.2.0/24 => App VMSS (Node.js) + ILB frontend
  • snet-db-bookstore-cent-ind : 10.0.3.0/24 => CosmosDB private endpoint NIC
  • AzureBastionSubnet 10.0.5.0/26 Azure Bastion (name must be exact)

The AGW subnet is dedicated. Azure will refuse to deploy an Application Gateway into any subnet that has other resources in it.

NSGs

Each subnet except AzureBastionSubnet gets its own Network Security Group.

The rule that tripped me in an earlier build, you need an AzureLoadBalancer service tag rule on the app subnet NSG, not just an allow rule from the web subnet.

The Internal Load Balancer sends health probe packets to each App VMSS instance from Azure’s internal platform IP 168.63.129.16. This IP doesn’t belong to any subnet, it’s Azure’s own fabric address. The AzureLoadBalancer service tag represents it. Without this rule, the ILB marks every App VMSS instance as unhealthy because its probe packets are silently dropped by the NSG. Your Node.js process runs perfectly. Zero traffic reaches it. No error message tells you why.

1 : AGW Subnet Nsg :

ports-for-health-deployment (Priority 100): Source GatewayManager, ports 65200–65535, TCP, Allow

AllowAzureLB (Priority 110): Source AzureLoadBalancer, Allow
# Azure App GW uses multuiple VM's underneath which are managed by internal LB so we need to allow them.

Allow-HTTP-HTTPS (Priority 120): Source Any, ports 80,443, Allow

2 : Web Subnet Nsg :

allow-http-agw-to-web (Priority 100): Source 10.0.0.0/24 (AGW subnet only), port 80, Allow
# The AGW decrypts HTTPS and forwards plain HTTP on port 80 to Nginx. TLS termination happens at the AGW. Nginx never sees an encrypted connection and never needs a certificate.

bastion rule aint mandatory

3 : App Subnet Nsg :

allow-web-subnet-on-5555 (Priority 100): Source 10.0.1.0/24 (web subnet), port 5555, TCP, Allow

allow-lb-probe (Priority 110): Source AzureLoadBalancer, Allow — this is the critical one

NAT Gateway :

Private VMs with no public IP can’t reach the internet for outbound traffic — meaning apt install, npm install, and any package download fails silently. The NAT Gateway gives them a shared outbound path without accepting any inbound connections.

I attached it to both the web and app subnets.

Bastion :

Rather than opening port 22 to the internet on my VMs, I use Azure Bastion which is a managed jump server that provides SSH access through the Azure portal browser over HTTPS. No public IP needed on any VM. The VMs never know port 22 was involved.

One important cost note: Bastion charges ~₹5–7/hour while running. I delete it when I’m not working and redeploy it (takes 5 minutes) when I need to SSH somewhere. Over a week of intermittent work, this saves significant cost.

**Part 2 : Identity, Storage & Key Vault**


메타데이터
post_id
ff0edd697a62
slug
3-tier-azure-iaas-mern-bookstore-part-1-network-foundation-vnet-subnets-nsgs-bastion-ff0edd697a62
url
https://medium.com/@guptetanish/3-tier-azure-iaas-mern-bookstore-part-1-network-foundation-vnet-subnets-nsgs-bastion-ff0edd697a62
canonical_url
https://medium.com/@guptetanish/3-tier-azure-iaas-mern-bookstore-part-1-network-foundation-vnet-subnets-nsgs-bastion-ff0edd697a62
author_url
https://medium.com/@guptetanish
status
ok
fetched_at
2026-09-03 19:15:01