Azure App Service Architecture, Deployment Slots, and VNet Integration 🌐⚡

Azure App Service is Microsoft’s fully managed Platform-as-a-Service (PaaS) for hosting web applications, RESTful APIs, and mobile backends. Running on both Linux and Windows operating systems, App Service abstracts operating system patching, runtime maintenance, load balancing, and infrastructure provisioning. It features enterprise capabilities including Deployment Slots with zero-downtime traffic warm-up, Regional Virtual Network (VNet) Integration, managed TLS certificates, and tight Microsoft Entra ID authentication integration.


1. Architecture & Multi-Tenant Topology

Azure App Service separates the underlying physical compute infrastructure—the App Service Plan (ASP)—from the logical applications hosted on top of it.

                           CLIENT BROWSER / API CONSUMER
                                         │
                                         ▼
     ┌────────────────────────────────────────────────────────────────────────┐
     │                      AZURE FRONT-END LOAD BALANCERS                    │
     │  - Terminates TLS (Custom Domains / Managed Free Certificates)         │
     │  - Routing layer: routes incoming requests to worker instances        │
     │  - Inspects deployment slot affinity cookies (x-ms-routing-name)       │
     └───────────────────────────────────┬────────────────────────────────────┘
                                         │
     ┌───────────────────────────────────┴────────────────────────────────────┐
     │                APP SERVICE PLAN (DEDICATED COMPUTE FLEET)              │
     │                                                                        │
     │  ┌────────────────────────┐         ┌────────────────────────┐         │
     │  │ Worker Instance 1      │         │ Worker Instance N      │         │
     │  │ ┌────────────────────┐ │         │ ┌────────────────────┐ │         │
     │  │ │ Production App     │ │         │ │ Production App     │ │         │
     │  │ └────────────────────┘ │         │ └────────────────────┘ │         │
     │  │ ┌────────────────────┐ │         │ ┌────────────────────┐ │         │
     │  │ │ Staging Slot App   │ │         │ │ Staging Slot App   │ │         │
     │  │ └────────────────────┘ │         │ └────────────────────┘ │         │
     │  └──────────┬─────────────┘         └──────────┬─────────────┘         │
     └─────────────┼──────────────────────────────────┼───────────────────────┘
                   │                                  │
     ══════════════╪══════════════════════════════════╪════════════════════════
                   │ REGIONAL VNET INTEGRATION        │ (Delegated Subnet)
                   ▼                                  ▼
     ┌────────────────────────────────────────────────────────────────────────┐
     │                  AZURE VIRTUAL NETWORK (VNET)                          │
     │                                                                        │
     │   - Private egress to Azure Database for PostgreSQL                    │
     │   - Private egress to Azure Cache for Redis via Private Endpoints      │
     │   - Cross-premises access via ExpressRoute or Site-to-Site VPN         │
     └────────────────────────────────────────────────────────────────────────┘

Core Architecture Constructs

  1. App Service Plan (ASP): Defines the compute region, OS (Linux/Windows), number of VM instances, and hardware SKU (e.g., Premium v3: P1v3, P2v3, P3v3). All web apps assigned to the same App Service Plan share the exact same underlying VM instances and RAM.
  2. Multi-Tenant vs App Service Environment (ASEv3):
    • Standard/Premium (Multi-Tenant): Worker VMs are dedicated to your subscription, but front-end load balancers and storage backplanes are shared across multiple Azure customers.
    • ASEv3 (Isolated): Complete single-tenant isolation deployed directly inside your private VNet with zero multi-tenant components, ideal for banking and defense compliance.
  3. Deployment Slots: Dedicated live web apps with independent hostnames running on the same App Service Plan. Slots enable testing releases in a production-identical environment before performing an instantaneous, zero-downtime DNS/socket swap with the production slot.
  4. Regional VNet Integration: Attaches the worker VMs to a dedicated delegated subnet in your Azure Virtual Network. While inbound traffic still flows through the public front ends (unless restricted by access rules or Private Endpoints), all outbound database and backend API calls route privately inside your VNet.

2. Zero-Downtime Deployment Slots Mechanics

A common anti-pattern is pushing new code directly to production, causing cold-start request latency and compilation errors. Deployment slots eliminate this via a two-phase swap:

Step 1: Deploy code to 'staging' slot (https://myapp-staging.azurewebsites.net)
Step 2: Trigger Slot Swap
        a. Azure applies production App Settings (non-slot) to the staging instance.
        b. Azure triggers an HTTP warm-up request against the application's root or custom probe path.
        c. Azure waits for the warm-up probe to return HTTP 200.
        d. Front-end load balancers swap virtual IP routing pointers instantly.
Result: Zero dropped TCP connections, zero cold-start latency for end users.

Slot Settings vs Unbound Settings

  • Standard Settings (Default): Swap along with the code (e.g., framework version, feature flags).
  • Deployment Slot Settings (Sticky): Pinned to the physical slot and never swap (e.g., database connection strings, external payment gateway endpoints, target logging workspace).

3. Production Deployment & CLI Operations (az)

1. Create a Premium v3 Linux App Service Plan

az group create --name rg-webapps-prod --location eastus
 
# Create Premium v3 App Service Plan with auto-scaling
az appservice plan create \
    --name asp-production-eastus \
    --resource-group rg-webapps-prod \
    --location eastus \
    --is-linux \
    --sku P1v3 \
    --number-of-workers 2

2. Configure Delegated Subnet for Regional VNet Integration

# Create VNet and delegated subnet for App Service
az network vnet create \
    --resource-group rg-webapps-prod \
    --name vnet-appservice-prod \
    --address-prefixes 10.200.0.0/16 \
    --subnet-name snet-appservice \
    --subnet-prefixes 10.200.1.0/24 \
    --delegations Microsoft.Web/serverFarms

3. Deploy Web App with VNet Integration & Managed Identity

# Deploy Web App running Node 20 LTS
az webapp create \
    --name app-ecommerce-core-prod \
    --resource-group rg-webapps-prod \
    --plan asp-production-eastus \
    --runtime "NODE:20-lts" \
    --assign-identity [system]
 
# Attach Regional VNet Integration
az webapp vnet-integration add \
    --name app-ecommerce-core-prod \
    --resource-group rg-webapps-prod \
    --vnet vnet-appservice-prod \
    --subnet snet-appservice
 
# Route ALL outbound traffic through VNet (Internet + Private IPs)
az webapp config set \
    --name app-ecommerce-core-prod \
    --resource-group rg-webapps-prod \
    --generic-configurations '{"vnetRouteAllEnabled": true}'

4. Create Staging Deployment Slot with Sticky Settings

# Create staging slot
az webapp deployment slot create \
    --name app-ecommerce-core-prod \
    --resource-group rg-webapps-prod \
    --slot staging
 
# Set sticky connection string for staging (does not swap)
az webapp config appsettings set \
    --name app-ecommerce-core-prod \
    --resource-group rg-webapps-prod \
    --slot staging \
    --slot-settings DATABASE_URL="postgresql://staging-db.internal:5432/app"
 
# Perform zero-downtime swap from staging to production
az webapp deployment slot swap \
    --name app-ecommerce-core-prod \
    --resource-group rg-webapps-prod \
    --slot staging \
    --target-slot production

5. Restrict Inbound Access via IP Security Rules

# Block all external public access, allow only Azure Front Door
az webapp config access-restriction add \
    --name app-ecommerce-core-prod \
    --resource-group rg-webapps-prod \
    --rule-name "AllowAzureFrontDoorOnly" \
    --action Allow \
    --ip-address AzureFrontDoor.Backend \
    --priority 100

4. Quotas, SKUs, and Performance Limits

SKU TiervCPU / RAM OptionsMax Instances (Scale Out)Deployment SlotsVNet Integration
Basic (B1-B3)1-4 vCPU / 1.75 - 7 GiB3 instances0 slotsSupported
Standard (S1-S3)1-4 vCPU / 1.75 - 7 GiB10 instances5 slotsSupported
Premium v3 (P1v3-P3v3)2-32 vCPU / 8 - 128 GiB30 instances (up to 100)20 slotsSupported
Isolated v2 (ASEv3)2-32 vCPU / 8 - 128 GiB200 instances200 slotsNative VNet injection
Outbound SNAT Limit128 ports per instanceMitigate via NAT Gateway or VNet integration
File Storage Quota250 GB (Pv3) / 1 TB (ASEv3)Mounted SMB/NFS share shared across instances

5. Official References & Documentation


6. Realistic Pricing Scenarios

App Service pricing is billed per hour for the App Service Plan, regardless of how many web apps are deployed on that plan:

  1. P1v3 (Linux): 2 vCPU, 8 GiB RAM = ~113.15/month).
  2. P2v3 (Linux): 4 vCPU, 16 GiB RAM = ~226.30/month).
  3. Deployment Slots: Incur $0 additional platform charge; they consume CPU and memory from the host App Service Plan.

Scenario A: Enterprise Corporate Portal with Staging Slot & VNet

  • Architecture:
    • 1 App Service Plan running P1v3 (2 instances for high availability = 4 vCPU, 16 GiB RAM total).
    • Web Apps: 1 Production Web App + 1 Staging Slot (running on the same ASP).
    • VNet Integration enabled into regional virtual network.
    • Azure NAT Gateway attached to subnet for dedicated outbound IP (0.045/GB).
  • Monthly Cost Calculation:
    • App Service Plan (2 × P1v3 instances): 2 \times \0.155/\text{hr} \times 730 \text{ hrs} = \mathbf{$226.30}$
    • Staging Slot: Included ($0.00)
    • VNet Integration: Included ($0.00)
    • NAT Gateway (Compute + 50 GB egress): (\0.045 \times 730) + (50 \times $0.045) = $32.85 + $2.25 = \mathbf{$35.10}$
  • Total Monthly Cost: $261.40 / month

Scenario B: High-Throughput E-Commerce Multi-App Consolidation

  • Architecture:
    • 1 App Service Plan running P2v3 (4 vCPU, 16 GiB RAM) scaling dynamically between 3 and 10 instances (average: 5 instances).
    • Host 6 independent microservices (Catalog, Cart, Checkout, Auth, Admin, Blog) on the same plan.
    • 5 instances running continuously (20 vCPUs, 80 GiB RAM fleet).
  • Monthly Cost Calculation:
    • App Service Plan Compute: 5 \times \0.310/\text{hr} \times 730 \text{ hrs} = \mathbf{$1{,}131.50}$
    • Cost per microservice ( apps): ~$188.58 per service / month.
  • Total Monthly Cost: $1,131.50 / month

7. Battle-Tested Nuggets & Production Gotchas

  1. The Shared App Service Plan Resource Contention Trap: All web apps and deployment slots assigned to an App Service Plan share the same CPU, RAM, and disk I/O. If an engineer performs a heavy stress test on a staging slot, or if one non-critical internal tool encounters an infinite loop, it will starve and crash the production customer-facing web app. Never co-locate mission-critical production apps with development/testing slots or noisy internal tools on the same App Service Plan.
  2. vnetRouteAllEnabled is Mandatory for Private Egress: When configuring Regional VNet Integration, by default Azure only routes RFC 1918 private IP traffic (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) through the VNet. All public traffic (including traffic to public endpoints of Azure SQL, Key Vault, or external APIs) exits via dynamic shared Azure outbound IP pools. To route all egress through your Azure Firewall or NAT Gateway, you must set vnetRouteAllEnabled=true.
  3. SNAT Port Exhaustion on Outbound HTTP Calls: In multi-tenant App Service without VNet integration, each instance has a fixed allocation of 128 SNAT ports. If your code opens new HTTP connections for every database or API call instead of reusing HttpClient or connection pooling, SNAT ports exhaust in seconds, resulting in SocketException: No connection could be made because the target machine actively refused it. Mitigate by enabling VNet integration backed by an Azure NAT Gateway (which provides 64,000 SNAT ports per IP).
  4. Slot Swap Pre-Warm Custom Action (applicationInitialization): During a slot swap, Azure checks if the app returns HTTP 200 on the root path /. If your application takes 30 seconds to compile Razor views, load caches, or establish database connection pools, Azure may swap traffic before the app is genuinely ready, resulting in 502 Bad Gateway errors for early requests. Configure the web.config or Linux startup script with <applicationInitialization> specifying exact health check paths to wait for before declaring warm-up complete.
  5. Sticky Settings Can Break Deployments Silently: If you mark an App Setting as “Deployment Slot Setting” (sticky), it remains on the slot and never swaps. If your application code in version 2 requires a new configuration key that was only added to the staging slot as a sticky setting, when the swap executes, the production slot will lack the setting and crash immediately upon receiving production traffic.
  6. Always Set WEBSITE_RUN_FROM_PACKAGE = 1: Deploying via standard FTP or Git sync copies files loosely into /home/site/wwwroot, leaving files locked while node or .NET runs, leading to partial file copy errors and runtime crashes. Setting WEBSITE_RUN_FROM_PACKAGE = 1 mounts a read-only zip package as the virtual file system, guaranteeing atomic zero-latency deployments without file lock conflicts.

Across the wiki