{"id":395,"date":"2026-04-13T22:06:45","date_gmt":"2026-04-13T22:06:45","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/azure-virtual-machine-scale-sets-tutorial-architecture-pricing-use-cases-and-hands-on-guide-for-compute\/"},"modified":"2026-04-13T22:06:45","modified_gmt":"2026-04-13T22:06:45","slug":"azure-virtual-machine-scale-sets-tutorial-architecture-pricing-use-cases-and-hands-on-guide-for-compute","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/azure-virtual-machine-scale-sets-tutorial-architecture-pricing-use-cases-and-hands-on-guide-for-compute\/","title":{"rendered":"Azure Virtual Machine Scale Sets Tutorial: Architecture, Pricing, Use Cases, and Hands-On Guide for Compute"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Category<\/h2>\n\n\n\n<p>Compute<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Introduction<\/h2>\n\n\n\n<p>Azure <strong>Virtual Machine Scale Sets<\/strong> is a Compute service for running and automatically scaling a <strong>group of identical (or near-identical) virtual machines (VMs)<\/strong>. It helps you deploy and manage many VMs as a single resource so you can handle traffic spikes, improve availability, and reduce operational overhead compared to managing individual VMs.<\/p>\n\n\n\n<p>In simple terms: <strong>you define one VM model (image, size, networking, extensions), set how many instances you want, and Azure keeps that fleet running and scaled<\/strong>\u2014often behind a load balancer\u2014so your application can handle changing demand.<\/p>\n\n\n\n<p>Technically, Virtual Machine Scale Sets (often shortened to <em>VMSS<\/em>) provides an orchestration layer over Azure Virtual Machines. You choose an orchestration mode (notably <strong>Uniform<\/strong> or <strong>Flexible<\/strong>, depending on your needs), integrate with Azure Load Balancer or Application Gateway, configure health probes and upgrade policies, and optionally attach Azure Monitor autoscale rules. Azure then manages instance placement, updates, and (in many scenarios) automatic repair\/replacement of unhealthy instances.<\/p>\n\n\n\n<p>The problem it solves is the classic \u201chow do I run <strong>N<\/strong> servers reliably and scale them up\/down without babysitting every instance?\u201d Virtual Machine Scale Sets gives you a structured way to run <strong>stateless<\/strong> (and in some cases semi-stateful) compute fleets for web tiers, APIs, batch workers, CI agents, and more.<\/p>\n\n\n\n<blockquote>\n<p>Service naming status: <strong>\u201cVirtual Machine Scale Sets\u201d is the current official Azure service name<\/strong> and is active. In documentation you\u2019ll see different capabilities depending on orchestration mode (Uniform vs Flexible). Always verify mode-specific behavior in the official docs before committing to a production design.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">2. What is Virtual Machine Scale Sets?<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Official purpose<\/h3>\n\n\n\n<p>Virtual Machine Scale Sets is designed to help you <strong>deploy, manage, and automatically scale<\/strong> a set of Azure VMs. The scale set acts as a single management boundary for a group of instances, which typically share configuration such as VM image, size, networking, and extensions.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Core capabilities<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Scale out\/in<\/strong> VM instances manually or automatically (via Azure Monitor autoscale)<\/li>\n<li><strong>High availability<\/strong> patterns with <strong>Availability Zones<\/strong> (region permitting) and load balancing<\/li>\n<li><strong>Centralized management<\/strong> of updates, configuration, extensions, and instance lifecycle operations<\/li>\n<li><strong>Health-based behaviors<\/strong> such as load balancer health probes and (in many designs) repair\/replacement of unhealthy instances<\/li>\n<li>Integration with common Azure building blocks (VNets, Load Balancer, Application Gateway, Managed Disks, Azure Monitor)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Major components<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Scale set resource (VMSS)<\/strong>: the top-level resource you manage<\/li>\n<li><strong>Instance model<\/strong>: the VM configuration (image, SKU, OS disk, data disks, NICs, extensions, boot diagnostics)<\/li>\n<li><strong>VM instances<\/strong>: the actual VMs created from the model<\/li>\n<li><strong>Autoscale settings<\/strong>: rules that change instance count based on metrics or schedules<\/li>\n<li><strong>Load balancing<\/strong>: Azure Load Balancer or Application Gateway to distribute traffic<\/li>\n<li><strong>Health signals<\/strong>: probes and application health reporting (mode\/capability dependent\u2014verify in docs)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Service type<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>IaaS Compute orchestration<\/strong> over Azure Virtual Machines (VMs)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Scope: regional and zonal<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Virtual Machine Scale Sets is a <strong>regional<\/strong> resource.<\/li>\n<li>You can design for <strong>zonal resiliency<\/strong> by placing instances across <strong>Availability Zones<\/strong> in regions that support zones.<\/li>\n<li>All resources still live inside an Azure <strong>subscription<\/strong>, <strong>resource group<\/strong>, and <strong>region<\/strong>.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">How it fits into the Azure ecosystem<\/h3>\n\n\n\n<p>Virtual Machine Scale Sets sits in the \u201cfleet compute\u201d layer:\n&#8211; It uses <strong>Azure Virtual Machines<\/strong> as the underlying compute.\n&#8211; It commonly pairs with:\n  &#8211; <strong>Azure Load Balancer<\/strong> (Layer 4) for TCP\/UDP traffic distribution\n  &#8211; <strong>Azure Application Gateway<\/strong> (Layer 7) for HTTP(S) routing + WAF options\n  &#8211; <strong>Azure Monitor<\/strong> for metrics, logs, autoscale, and alerts\n  &#8211; <strong>Azure Virtual Network (VNet)<\/strong> for networking\n  &#8211; <strong>Azure Key Vault<\/strong> for secrets\/certificates (accessed via Managed Identity)\n  &#8211; <strong>Azure Compute Gallery<\/strong> (formerly Shared Image Gallery) for custom images<\/p>\n\n\n\n<p>Official docs entry point: https:\/\/learn.microsoft.com\/azure\/virtual-machine-scale-sets\/<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">3. Why use Virtual Machine Scale Sets?<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Business reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Handle growth without redesign<\/strong>: add capacity when demand increases.<\/li>\n<li><strong>Improve uptime<\/strong>: distribute instances across fault domains \/ availability zones and replace unhealthy nodes.<\/li>\n<li><strong>Lower toil<\/strong>: manage one scale set instead of dozens\/hundreds of separate VM resources.<\/li>\n<li><strong>Predictable deployments<\/strong>: \u201cgolden image + scale set model\u201d helps standardize environments.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Technical reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Horizontal scalability<\/strong>: add more VMs to increase throughput.<\/li>\n<li><strong>Integration with load balancing<\/strong>: place a stable frontend in front of changing backends.<\/li>\n<li><strong>Immutable-ish infra pattern<\/strong>: update by rolling out a new image\/model rather than patching every VM manually (design-dependent).<\/li>\n<li><strong>Autoscale<\/strong> based on CPU, memory (via guest metrics), queue length (with custom metrics), or schedules.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Operational reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Central place to:<\/li>\n<li>Scale<\/li>\n<li>Upgrade (rolling upgrades in many patterns)<\/li>\n<li>Apply extensions<\/li>\n<li>Run commands across instances<\/li>\n<li>Monitor health and capacity<\/li>\n<li>Enables \u201ccattle not pets\u201d operations for stateless tiers.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Security\/compliance reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Standardize baseline hardening (image + extensions).<\/li>\n<li>Control access via <strong>Azure RBAC<\/strong> and <strong>Managed Identity<\/strong>.<\/li>\n<li>Improve auditability through Azure Activity Log and Azure Monitor logging.<\/li>\n<li>Use network isolation with VNets, NSGs, private subnets, and controlled inbound paths.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Scalability\/performance reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Add instances to absorb spikes.<\/li>\n<li>Distribute load across zones for resiliency and latency improvement (regional considerations apply).<\/li>\n<li>Reduce single-node bottlenecks by scaling workers and web tiers horizontally.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">When teams should choose it<\/h3>\n\n\n\n<p>Choose Virtual Machine Scale Sets when you need:\n&#8211; A <strong>VM-based<\/strong> compute fleet (OS access, custom binaries, special drivers, legacy software).\n&#8211; <strong>Predictable scaling<\/strong> and availability.\n&#8211; Integration with <strong>VNets<\/strong>, <strong>load balancers<\/strong>, and enterprise networking patterns.\n&#8211; A path that\u2019s \u201cmore controllable than PaaS,\u201d but less manual than managing individual VMs.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">When teams should not choose it<\/h3>\n\n\n\n<p>Avoid or reconsider VMSS if:\n&#8211; You don\u2019t need VM-level control and prefer simpler operations (consider <strong>Azure App Service<\/strong>, <strong>Azure Container Apps<\/strong>, or <strong>Azure Functions<\/strong>).\n&#8211; Your workload is primarily containerized and you want Kubernetes orchestration (consider <strong>Azure Kubernetes Service (AKS)<\/strong>).\n&#8211; Your application is heavily stateful on local disk and can\u2019t tolerate instance replacement without careful state management.\n&#8211; You need a single powerful machine rather than a horizontally scaled fleet (consider a standalone Azure VM or specialized services).<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">4. Where is Virtual Machine Scale Sets used?<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Industries<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>SaaS and software companies (web\/API tiers, background workers)<\/li>\n<li>Finance and insurance (risk compute, batch processing, regulated environments)<\/li>\n<li>Retail\/e-commerce (traffic bursts, seasonal spikes)<\/li>\n<li>Media\/streaming (transcoding workers, content pipelines)<\/li>\n<li>Manufacturing\/IoT backends (ingestion processors)<\/li>\n<li>Education (labs, training environments)<\/li>\n<li>Gaming (matchmaking services, scalable backends)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Team types<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Platform engineering teams building reusable infrastructure patterns<\/li>\n<li>DevOps\/SRE teams operating scalable services<\/li>\n<li>Application teams needing VM-level dependencies<\/li>\n<li>Security teams enforcing standardized images and access controls<\/li>\n<li>Data\/ML engineering teams running batch\/worker fleets on VMs<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Workloads<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Stateless web frontends<\/li>\n<li>REST\/gRPC API services<\/li>\n<li>CI\/CD build agents (self-hosted runners)<\/li>\n<li>Queue-driven workers (processing jobs from Service Bus\/Storage queues)<\/li>\n<li>Batch compute nodes (sometimes alongside Azure Batch)<\/li>\n<li>Compute-intensive processing (rendering, simulation) where horizontal scale helps<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Architectures<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Classic 3-tier (web tier in VMSS, app tier in VMSS, data tier managed service)<\/li>\n<li>Microservices hosted on VMs (when containers aren\u2019t an option)<\/li>\n<li>Hybrid hub-and-spoke VNets with shared egress and centralized security controls<\/li>\n<li>Blue\/green or canary deployments using multiple scale sets behind traffic routing<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Real-world deployment contexts<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Production<\/strong>: zonal scale sets behind WAF + Application Gateway, integrated monitoring, controlled rollout policies.<\/li>\n<li><strong>Dev\/test<\/strong>: small instance count, manual scale, scheduled scale-out for load tests, then scale-in to reduce cost.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">5. Top Use Cases and Scenarios<\/h2>\n\n\n\n<p>Below are 10 realistic ways teams use Virtual Machine Scale Sets.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1) Autoscaling web tier behind a load balancer<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem<\/strong>: Web traffic varies; static server counts either overload or waste money.<\/li>\n<li><strong>Why VMSS fits<\/strong>: Scale out\/in automatically, integrate with Azure Load Balancer or Application Gateway.<\/li>\n<li><strong>Example<\/strong>: Two instances at baseline; scale to 10 during peak shopping hours.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2) API service tier with rolling image upgrades<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem<\/strong>: Updating 30 VMs without downtime is hard.<\/li>\n<li><strong>Why VMSS fits<\/strong>: Model-based deployment supports rolling upgrades in many designs.<\/li>\n<li><strong>Example<\/strong>: Bake a new image version; roll across instances while keeping capacity.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">3) Queue-driven background workers<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem<\/strong>: Job backlog grows; workers need to scale with queue depth.<\/li>\n<li><strong>Why VMSS fits<\/strong>: Autoscale can be driven by metrics; instances are interchangeable.<\/li>\n<li><strong>Example<\/strong>: Process images from a queue; scale out when queue length increases (custom metric pattern).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">4) Self-hosted CI\/CD agents<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem<\/strong>: Build bursts cause long queue times; idle agents waste budget.<\/li>\n<li><strong>Why VMSS fits<\/strong>: Quickly scale build agents, replace unhealthy agents automatically.<\/li>\n<li><strong>Example<\/strong>: Scale out to 50 build agents during work hours, scale in at night.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">5) Stateless game backend services<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem<\/strong>: Player count spikes after releases\/events.<\/li>\n<li><strong>Why VMSS fits<\/strong>: Horizontal scaling + load balancing.<\/li>\n<li><strong>Example<\/strong>: Matchmaking API scales from 5 to 40 instances.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">6) Batch processing fleet for nightly jobs<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem<\/strong>: Need large compute only during a limited processing window.<\/li>\n<li><strong>Why VMSS fits<\/strong>: Schedule-based autoscale patterns reduce cost.<\/li>\n<li><strong>Example<\/strong>: Scale to 100 instances from 1 AM\u20133 AM for ETL processing, scale back to 0\u20132.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">7) Edge-like regional deployment for latency<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem<\/strong>: Users in multiple geographies need low latency.<\/li>\n<li><strong>Why VMSS fits<\/strong>: Deploy scale sets per region, front with Azure Front Door.<\/li>\n<li><strong>Example<\/strong>: VMSS in East US + West Europe; Front Door routes users to closest region.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">8) GPU worker nodes for rendering\/transcoding<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem<\/strong>: Need bursts of GPU compute.<\/li>\n<li><strong>Why VMSS fits<\/strong>: VMSS can manage a fleet of GPU-enabled VMs (SKU availability varies by region\u2014verify).<\/li>\n<li><strong>Example<\/strong>: Video transcode workers scale to meet upload demand.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">9) Legacy application modernization (lift-and-improve)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem<\/strong>: Legacy app needs VMs and can\u2019t be containerized easily.<\/li>\n<li><strong>Why VMSS fits<\/strong>: VM-based deployment, but with modern scaling and health.<\/li>\n<li><strong>Example<\/strong>: Migrate IIS-based app to VMSS; use Application Gateway for HTTP routing.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">10) Zero-trust hardened \u201ccompute pool\u201d<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem<\/strong>: Need standardized hardened nodes with controlled outbound and no inbound SSH.<\/li>\n<li><strong>Why VMSS fits<\/strong>: One hardened image + policy + NSG; operational access via Azure Bastion\/Run Command.<\/li>\n<li><strong>Example<\/strong>: Workers in private subnet access storage via private endpoints; no public IPs.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">6. Core Features<\/h2>\n\n\n\n<blockquote>\n<p>Note: Some features differ by orchestration mode (<strong>Uniform<\/strong> vs <strong>Flexible<\/strong>) and by VM image\/OS. Validate mode-specific details in official docs before adopting.<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">1) Orchestration modes (Uniform and Flexible)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does<\/strong>: Determines how Azure manages VM instances and what features are available.<\/li>\n<li><strong>Why it matters<\/strong>: It affects upgrade behavior, scaling semantics, and VM feature parity.<\/li>\n<li><strong>Practical benefit<\/strong>: Pick Uniform for classic identical-instance fleets; pick Flexible for scenarios needing more VM-like behaviors (verify capability matrix).<\/li>\n<li><strong>Caveats<\/strong>: Not all features exist in both modes; confirm requirements early.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2) Autoscaling (Azure Monitor autoscale)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does<\/strong>: Automatically changes instance count based on metrics (CPU, custom metrics) or schedules.<\/li>\n<li><strong>Why it matters<\/strong>: Keeps performance stable while controlling cost.<\/li>\n<li><strong>Practical benefit<\/strong>: Scale out under load, scale in when idle.<\/li>\n<li><strong>Caveats<\/strong>: Autoscale reacts to metrics with some delay; plan capacity buffers.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">3) Manual scaling<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does<\/strong>: You set the instance count directly.<\/li>\n<li><strong>Why it matters<\/strong>: Useful for predictable or controlled scaling events (deployments, load tests).<\/li>\n<li><strong>Practical benefit<\/strong>: Simple and deterministic.<\/li>\n<li><strong>Caveats<\/strong>: Manual scaling alone doesn\u2019t respond to sudden spikes.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">4) Integration with Azure Load Balancer<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does<\/strong>: Distributes L4 traffic (TCP\/UDP) across instances.<\/li>\n<li><strong>Why it matters<\/strong>: Provides a stable frontend IP\/DNS while backend instances change.<\/li>\n<li><strong>Practical benefit<\/strong>: Common for web\/API traffic and non-HTTP protocols.<\/li>\n<li><strong>Caveats<\/strong>: Health probes must be correct; Standard Load Balancer is common for production.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">5) Integration with Azure Application Gateway<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does<\/strong>: Distributes HTTP(S) traffic with L7 routing features; supports WAF SKUs.<\/li>\n<li><strong>Why it matters<\/strong>: Enables path-based routing, TLS termination, cookie affinity, WAF policies.<\/li>\n<li><strong>Practical benefit<\/strong>: Better for complex HTTP routing than a basic L4 load balancer.<\/li>\n<li><strong>Caveats<\/strong>: Costs and configuration complexity are higher than Load Balancer.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">6) Availability Zones support (region permitting)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does<\/strong>: Spreads instances across zones to survive a zonal outage.<\/li>\n<li><strong>Why it matters<\/strong>: Improves resiliency and availability.<\/li>\n<li><strong>Practical benefit<\/strong>: Zone-redundant design for critical tiers.<\/li>\n<li><strong>Caveats<\/strong>: Zone support varies by region and SKU; verify.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">7) VM image flexibility (Marketplace, custom images, Azure Compute Gallery)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does<\/strong>: Lets you use Microsoft\/Azure Marketplace images or your own golden images.<\/li>\n<li><strong>Why it matters<\/strong>: Standardizes OS + packages + hardening.<\/li>\n<li><strong>Practical benefit<\/strong>: Faster provisioning, consistent security posture.<\/li>\n<li><strong>Caveats<\/strong>: Image versioning and rollout must be managed carefully.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">8) Extensions and cloud-init\/custom data<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does<\/strong>: Bootstrap configuration at provision time (install packages, configure apps).<\/li>\n<li><strong>Why it matters<\/strong>: Reduces manual steps and drift.<\/li>\n<li><strong>Practical benefit<\/strong>: Deploy \u201cready-to-serve\u201d instances automatically.<\/li>\n<li><strong>Caveats<\/strong>: Overusing extensions can slow provisioning; prefer baked images for large fleets.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">9) Upgrade policies and rolling upgrades (mode-dependent)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does<\/strong>: Controls how updates are applied across instances.<\/li>\n<li><strong>Why it matters<\/strong>: Minimizes downtime and risk.<\/li>\n<li><strong>Practical benefit<\/strong>: Controlled rollout with capacity preserved.<\/li>\n<li><strong>Caveats<\/strong>: Behavior varies by orchestration mode and configuration; verify exact capabilities.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">10) Automatic instance repair \/ health-based replacement (design-dependent)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does<\/strong>: Detects unhealthy instances and replaces or repairs them.<\/li>\n<li><strong>Why it matters<\/strong>: Improves availability without manual intervention.<\/li>\n<li><strong>Practical benefit<\/strong>: Faster recovery from node-level failures.<\/li>\n<li><strong>Caveats<\/strong>: \u201cUnhealthy\u201d depends on signals (LB probe, application health). Misconfigured probes can cause churn.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">11) Spot instances (cost optimization pattern)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does<\/strong>: Allows using Azure Spot VMs in scale sets (when suitable).<\/li>\n<li><strong>Why it matters<\/strong>: Can reduce compute cost significantly for interruptible workloads.<\/li>\n<li><strong>Practical benefit<\/strong>: Great for batch, CI, and fault-tolerant workers.<\/li>\n<li><strong>Caveats<\/strong>: Spot VMs can be evicted; design for interruption.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">12) Managed disks and disk options<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does<\/strong>: Uses Azure Managed Disks for OS and data.<\/li>\n<li><strong>Why it matters<\/strong>: Managed disks simplify storage management and reliability.<\/li>\n<li><strong>Practical benefit<\/strong>: Standardized, managed storage with performance tiers.<\/li>\n<li><strong>Caveats<\/strong>: Disk costs and performance tiers can dominate cost; plan carefully.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">13) Diagnostics and monitoring integration<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does<\/strong>: Emits metrics\/logs for performance, health, and operations.<\/li>\n<li><strong>Why it matters<\/strong>: Scaling and reliability depend on observability.<\/li>\n<li><strong>Practical benefit<\/strong>: Alert on CPU, memory, failed health probes, instance count, etc.<\/li>\n<li><strong>Caveats<\/strong>: Log ingestion has cost; define retention and sampling.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">7. Architecture and How It Works<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">High-level architecture<\/h3>\n\n\n\n<p>A typical VMSS-based application tier looks like:\n&#8211; Clients connect to a <strong>stable endpoint<\/strong> (public IP, DNS, Application Gateway, Front Door).\n&#8211; Traffic is distributed to VMSS instances through a <strong>load balancer<\/strong>.\n&#8211; Instances run identical app versions (or controlled mix during upgrades).\n&#8211; Health probes determine which instances receive traffic.\n&#8211; Autoscale changes instance count based on demand metrics.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Request\/data\/control flow<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Data plane (request path)<\/strong>:\n  1. Client requests <code>https:\/\/app.example.com<\/code>\n  2. (Optional) Azure Front Door routes to a region\n  3. Application Gateway or Load Balancer forwards to VMSS instance\n  4. Instance processes request and interacts with data services (SQL, Storage, Redis)<\/li>\n<li><strong>Control plane (management path)<\/strong>:<\/li>\n<li>You change the VMSS model, instance count, or autoscale rules via Azure Portal, Azure CLI, ARM\/Bicep, or Terraform.<\/li>\n<li>Azure Resource Manager applies changes; VMSS orchestration creates\/removes\/updates instances.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Integrations with related services<\/h3>\n\n\n\n<p>Common integrations include:\n&#8211; <strong>Azure Load Balancer<\/strong>: L4 load distribution and health probes\n&#8211; <strong>Azure Application Gateway<\/strong>: L7 routing and WAF\n&#8211; <strong>Azure Front Door<\/strong>: global routing, caching, TLS at the edge (for multi-region)\n&#8211; <strong>Azure Monitor<\/strong>: metrics, autoscale, alerts\n&#8211; <strong>Log Analytics workspace<\/strong>: centralized logging (via Azure Monitor Agent)\n&#8211; <strong>Azure Key Vault<\/strong>: secrets\/certs, often accessed using Managed Identity\n&#8211; <strong>Azure Compute Gallery<\/strong>: image management and versioning\n&#8211; <strong>Azure Policy<\/strong>: enforce tags, SKUs, security baselines\n&#8211; <strong>Microsoft Defender for Cloud<\/strong>: security posture management and recommendations (verify licensing requirements)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Dependency services<\/h3>\n\n\n\n<p>VMSS depends on:\n&#8211; <strong>Azure Compute<\/strong> capacity in the chosen region\/SKU\n&#8211; <strong>Networking<\/strong> (VNet\/subnet, NSG, route tables)\n&#8211; <strong>Storage<\/strong> for managed disks and (optionally) boot diagnostics\n&#8211; <strong>Identity<\/strong> (Entra ID \/ Azure AD) for RBAC and Managed Identity usage<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Security\/authentication model<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Management access<\/strong> uses Azure RBAC (Entra ID identities, service principals, managed identities).<\/li>\n<li>VM-to-Azure-service access commonly uses <strong>Managed Identity<\/strong> + role assignments.<\/li>\n<li>Admin access to the OS uses SSH keys (Linux) or secure credential management (Windows), ideally without exposing public management ports.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Networking model<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Instances attach NICs into a <strong>subnet<\/strong>.<\/li>\n<li>Inbound traffic is typically via Load Balancer\/App Gateway; instances usually do <strong>not<\/strong> need public IPs.<\/li>\n<li>Outbound traffic depends on design: NAT Gateway, Load Balancer outbound rules, Azure Firewall, or direct SNAT behavior (choose explicitly for production).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Monitoring\/logging\/governance considerations<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Metrics: VMSS instance count, CPU, network, disk, probe health.<\/li>\n<li>Logs: OS\/application logs via Azure Monitor Agent to Log Analytics.<\/li>\n<li>Governance: consistent tags, naming, policy enforcement; track changes in Activity Log.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Simple architecture diagram (Mermaid)<\/h3>\n\n\n\n<pre><code class=\"language-mermaid\">flowchart LR\n  U[Users] --&gt; PIP[Public Endpoint]\n  PIP --&gt; LB[Azure Load Balancer]\n  LB --&gt; VMSS[Virtual Machine Scale Sets&lt;br\/&gt;VM instances]\n  VMSS --&gt; DATA[(Data service&lt;br\/&gt;e.g., Azure SQL\/Storage)]\n  VMSS --&gt; MON[Azure Monitor]\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Production-style architecture diagram (Mermaid)<\/h3>\n\n\n\n<pre><code class=\"language-mermaid\">flowchart TB\n  Users[Internet Users] --&gt; FD[Azure Front Door&lt;br\/&gt;Global routing + TLS]\n  FD --&gt; WAF[Application Gateway (WAF)&lt;br\/&gt;Regional L7 routing]\n  WAF --&gt; LB[Internal\/Regional Load Balancer&lt;br\/&gt;or App Gateway backend pool]\n\n  subgraph VNet[Azure Virtual Network]\n    subgraph WebSubnet[Web Subnet]\n      VMSS[VMSS across Availability Zones]\n    end\n\n    subgraph DataSubnet[Data\/Private Subnet]\n      KV[Azure Key Vault&lt;br\/&gt;(Private Endpoint)]\n      ST[Azure Storage&lt;br\/&gt;(Private Endpoint)]\n      SQL[Azure SQL&lt;br\/&gt;(Private Endpoint optional)]\n    end\n\n    VMSS --&gt; KV\n    VMSS --&gt; ST\n    VMSS --&gt; SQL\n  end\n\n  VMSS --&gt; AM[Azure Monitor Metrics]\n  VMSS --&gt; LA[Log Analytics Workspace]\n  AM --&gt; AS[Autoscale Rules]\n  SOC[Security Team] --&gt; Def[Defender for Cloud]\n  Def --&gt; VNet\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">8. Prerequisites<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Account\/subscription\/tenant requirements<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>An active <strong>Azure subscription<\/strong> with billing enabled.<\/li>\n<li>Access to an <strong>Azure resource group<\/strong> in a supported region.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Permissions \/ IAM roles<\/h3>\n\n\n\n<p>Minimum recommended permissions for the lab:\n&#8211; At subscription or resource-group scope:\n  &#8211; <strong>Contributor<\/strong> (for creating resources), or\n  &#8211; A combination of roles allowing Compute\/Network\/Monitor creation\n&#8211; If using policies\/locked-down environments, you may need additional permissions for:\n  &#8211; Creating public IPs \/ load balancers\n  &#8211; Creating autoscale settings\n  &#8211; Creating managed identities (optional)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Billing requirements<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You will incur charges for:<\/li>\n<li>VM compute (per second\/minute depending on billing model\u2014see VM pricing)<\/li>\n<li>Managed disks<\/li>\n<li>Public IP and Load Balancer (SKU dependent)<\/li>\n<li>Monitoring\/log ingestion if enabled<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">CLI\/SDK\/tools needed<\/h3>\n\n\n\n<p>Choose one:\n&#8211; <strong>Azure Cloud Shell<\/strong> (recommended for quick labs): https:\/\/shell.azure.com\/\n&#8211; Or install locally:\n  &#8211; <strong>Azure CLI<\/strong>: https:\/\/learn.microsoft.com\/cli\/azure\/install-azure-cli<\/p>\n\n\n\n<p>Optional tools:\n&#8211; <code>ssh<\/code> client (Linux\/macOS\/Windows)\n&#8211; <code>curl<\/code> for HTTP tests<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Region availability<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Virtual Machine Scale Sets is widely available. Availability Zones and certain VM SKUs vary by region.<\/li>\n<li>Verify region features: https:\/\/azure.microsoft.com\/explore\/global-infrastructure\/products-by-region\/<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Quotas\/limits<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>VMSS is constrained by:<\/li>\n<li>Regional <strong>vCPU quota<\/strong> for the chosen VM family<\/li>\n<li>Subscription and regional limits for public IPs, NICs, and other resources<\/li>\n<li>VMSS-specific limits (instance count, placement behavior) that can vary by orchestration mode<br\/>\n  Verify limits: https:\/\/learn.microsoft.com\/azure\/azure-resource-manager\/management\/azure-subscription-service-limits<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Prerequisite services<\/h3>\n\n\n\n<p>For common architectures:\n&#8211; Azure Virtual Network\n&#8211; Azure Load Balancer or Application Gateway\n&#8211; Azure Monitor (for autoscale\/alerts)<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">9. Pricing \/ Cost<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Pricing model (accurate, no fabricated numbers)<\/h3>\n\n\n\n<p><strong>Virtual Machine Scale Sets itself does not have a separate \u201cVMSS fee\u201d<\/strong> in typical billing. You pay for the underlying resources you deploy, including:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Compute<\/strong>: VM instances (Azure Virtual Machines pricing by size\/SKU, OS, region)<\/li>\n<li><strong>Storage<\/strong>: managed disks (OS and data), snapshots, images (if stored), and storage transactions where applicable<\/li>\n<li><strong>Networking<\/strong>:<\/li>\n<li>Load Balancer (SKU and rules can affect cost)<\/li>\n<li>Public IP addresses (SKU dependent)<\/li>\n<li>Bandwidth\/data transfer (egress is typically billable; ingress often free\u2014verify current bandwidth pricing)<\/li>\n<li>NAT Gateway\/Azure Firewall (if used)<\/li>\n<li><strong>Monitoring<\/strong>:<\/li>\n<li>Azure Monitor metrics are generally included at basic levels, but<\/li>\n<li><strong>Log Analytics ingestion and retention<\/strong> are billable<\/li>\n<li><strong>Optional security services<\/strong>:<\/li>\n<li>Defender for Cloud plans (if enabled) can add cost\u2014verify plan and scope<\/li>\n<\/ul>\n\n\n\n<p>Official VMSS docs: https:\/\/learn.microsoft.com\/azure\/virtual-machine-scale-sets\/<br\/>\nAzure Pricing Calculator: https:\/\/azure.microsoft.com\/pricing\/calculator\/<br\/>\nAzure Virtual Machines pricing: https:\/\/azure.microsoft.com\/pricing\/details\/virtual-machines\/<br\/>\nAzure Load Balancer pricing: https:\/\/azure.microsoft.com\/pricing\/details\/load-balancer\/<br\/>\nBandwidth pricing: https:\/\/azure.microsoft.com\/pricing\/details\/bandwidth\/<br\/>\nManaged Disks pricing: https:\/\/azure.microsoft.com\/pricing\/details\/managed-disks\/<br\/>\nAzure Monitor pricing: https:\/\/azure.microsoft.com\/pricing\/details\/monitor\/<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pricing dimensions<\/h3>\n\n\n\n<p>Key pricing dimensions to understand:\n&#8211; VM size (vCPU\/RAM), region, and OS licensing (Linux vs Windows)\n&#8211; Disk type and size (Standard HDD\/SSD, Premium SSD, Ultra Disk where applicable)\n&#8211; Instance count (baseline + peak)\n&#8211; Outbound data volume (internet egress)\n&#8211; Monitoring ingestion volume (GB\/day) and retention period\n&#8211; Additional components (WAF, NAT Gateway, Firewall, Bastion)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Free tier<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>There is no universal \u201cfree tier\u201d for VMSS fleets; some accounts may have Azure free credits. VM compute generally incurs charges.<\/li>\n<li>Some services have limited free quotas (varies; verify in official pricing pages).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Cost drivers (what usually makes VMSS expensive)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Over-provisioning<\/strong>: running too many instances all the time<\/li>\n<li><strong>Wrong VM SKU<\/strong>: using larger VMs instead of scaling out smaller ones (or vice versa)<\/li>\n<li><strong>Premium disks everywhere<\/strong>: premium storage on non-critical tiers<\/li>\n<li><strong>Logging everything<\/strong>: verbose logs into Log Analytics without retention controls<\/li>\n<li><strong>Outbound traffic<\/strong>: significant egress to internet or cross-region transfers<\/li>\n<li><strong>Perimeter components<\/strong>: Application Gateway WAF, Azure Firewall, Front Door can exceed VM costs for small fleets<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Hidden\/indirect costs to watch<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Public IP + Load Balancer SKU<\/strong> costs in production designs<\/li>\n<li><strong>Autoscale oscillation<\/strong>: frequent scale in\/out can create churn and operational overhead<\/li>\n<li><strong>Image build pipeline<\/strong>: Compute Gallery storage and CI build minutes<\/li>\n<li><strong>Backup<\/strong>: Recovery Services vault or snapshots if used<\/li>\n<li><strong>Patch management tooling<\/strong>: Update management solutions and their data ingestion<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Network\/data transfer implications<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Design for <strong>private endpoints<\/strong> and same-region dependencies to reduce egress\/cross-region charges.<\/li>\n<li>If clients are global, consider <strong>Front Door<\/strong>; but evaluate its cost against performance needs.<\/li>\n<li>For outbound internet access, choose an explicit strategy (NAT Gateway\/Firewall) to control SNAT and logging costs.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">How to optimize cost (practical)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Set <strong>autoscale min\/max<\/strong> and choose a realistic baseline.<\/li>\n<li>Use <strong>scheduled scaling<\/strong> when patterns are predictable.<\/li>\n<li>Consider <strong>Spot VMs<\/strong> for interruptible worker pools.<\/li>\n<li>Right-size VM SKUs using observed metrics (CPU, memory, IO).<\/li>\n<li>Choose disk tiers per workload and consider ephemeral OS disks where appropriate (verify suitability).<\/li>\n<li>Apply log ingestion controls:<\/li>\n<li>collect only needed logs<\/li>\n<li>set retention policies<\/li>\n<li>route high-volume logs to cheaper storage if appropriate<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Example low-cost starter estimate (how to think about it)<\/h3>\n\n\n\n<p>A low-cost lab usually includes:\n&#8211; 1 small Standard Load Balancer + 1 Public IP\n&#8211; 2 small Linux VMs (e.g., B-series or small D-series\u2014availability varies)\n&#8211; Standard OS disks\n&#8211; Minimal logging<\/p>\n\n\n\n<p>Exact prices vary by region and VM SKU. Use the <strong>Pricing Calculator<\/strong> with your region and expected hours.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Example production cost considerations<\/h3>\n\n\n\n<p>In production, your monthly cost is often dominated by:\n&#8211; Baseline instance count * VM hourly rate\n&#8211; Premium storage for performance-sensitive apps\n&#8211; WAF\/App Gateway\/Front Door + logging\n&#8211; NAT Gateway\/Firewall for controlled egress\n&#8211; Log Analytics ingestion and retention\n&#8211; Multi-zone or multi-region deployments (duplicated capacity)<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">10. Step-by-Step Hands-On Tutorial<\/h2>\n\n\n\n<p>This lab deploys a small, low-cost web fleet using <strong>Virtual Machine Scale Sets<\/strong>, installs NGINX automatically, and configures <strong>autoscale<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Objective<\/h3>\n\n\n\n<p>Deploy an Ubuntu-based Virtual Machine Scale Sets web tier behind an Azure Load Balancer, verify HTTP traffic distribution, and configure Azure Monitor autoscale rules.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lab Overview<\/h3>\n\n\n\n<p>You will:\n1. Create a resource group.\n2. Create a cloud-init config to install and customize NGINX.\n3. Create a Virtual Machine Scale Sets with a public load balancer endpoint.\n4. Test access via the load balancer public IP\/DNS.\n5. Configure autoscale rules based on CPU.\n6. (Optional) Generate CPU load to observe scaling.\n7. Clean up all resources.<\/p>\n\n\n\n<p><strong>Estimated time<\/strong>: 30\u201360 minutes<br\/>\n<strong>Cost<\/strong>: Depends on VM SKU and runtime; keep instance counts small and delete resources afterward.<\/p>\n\n\n\n<blockquote>\n<p>You can run this in <strong>Azure Cloud Shell (Bash)<\/strong> to avoid local setup.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Set variables and create a resource group<\/h3>\n\n\n\n<p>In Cloud Shell (Bash) or your terminal:<\/p>\n\n\n\n<pre><code class=\"language-bash\"># Change these to your preference\nexport LOCATION=\"eastus\"\nexport RG=\"rg-vmss-lab\"\nexport VMSS=\"vmss-web\"\nexport ADMIN_USER=\"azureuser\"\n\naz account show &gt;\/dev\/null 2&gt;&amp;1 || az login\n\naz group create \\\n  --name \"$RG\" \\\n  --location \"$LOCATION\"\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome<\/strong>: A resource group exists in your chosen region.<\/p>\n\n\n\n<p>Verify:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az group show --name \"$RG\" --query \"{name:name, location:location}\" -o table\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Create cloud-init to install NGINX and return instance identity<\/h3>\n\n\n\n<p>Create a file named <code>cloud-init.txt<\/code>:<\/p>\n\n\n\n<pre><code class=\"language-bash\">cat &gt; cloud-init.txt &lt;&lt;'EOF'\n#cloud-config\npackage_update: true\npackages:\n  - nginx\nwrite_files:\n  - path: \/var\/www\/html\/index.html\n    permissions: '0644'\n    owner: root:root\n    content: |\n      &lt;html&gt;\n      &lt;head&gt;&lt;title&gt;VMSS NGINX&lt;\/title&gt;&lt;\/head&gt;\n      &lt;body&gt;\n        &lt;h1&gt;Hello from Azure Virtual Machine Scale Sets&lt;\/h1&gt;\n        &lt;p&gt;Hostname: &lt;b&gt;__HOSTNAME__&lt;\/b&gt;&lt;\/p&gt;\n      &lt;\/body&gt;\n      &lt;\/html&gt;\nruncmd:\n  - sed -i \"s\/__HOSTNAME__\/$(hostname)\/g\" \/var\/www\/html\/index.html\n  - systemctl enable nginx\n  - systemctl restart nginx\nEOF\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome<\/strong>: A cloud-init file exists locally.<\/p>\n\n\n\n<p>Verify:<\/p>\n\n\n\n<pre><code class=\"language-bash\">head -n 20 cloud-init.txt\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Create the Virtual Machine Scale Sets<\/h3>\n\n\n\n<p>This command creates a VMSS and (for simplicity) also creates supporting resources such as:\n&#8211; VNet + subnet\n&#8211; NSG rules for inbound HTTP\n&#8211; Standard Load Balancer + public IP (depending on parameters)<\/p>\n\n\n\n<blockquote>\n<p>Azure CLI behavior can change over time; if any parameter differs in your environment, verify with <code>az vmss create -h<\/code> and the official docs.<\/p>\n<\/blockquote>\n\n\n\n<pre><code class=\"language-bash\"># DNS name must be globally unique in Azure for the chosen region\nexport DNS_NAME=\"vmsslab$RANDOM$RANDOM\"\n\naz vmss create \\\n  --resource-group \"$RG\" \\\n  --name \"$VMSS\" \\\n  --location \"$LOCATION\" \\\n  --image \"Ubuntu2204\" \\\n  --admin-username \"$ADMIN_USER\" \\\n  --generate-ssh-keys \\\n  --instance-count 2 \\\n  --vm-sku \"Standard_B1s\" \\\n  --upgrade-policy-mode \"automatic\" \\\n  --custom-data cloud-init.txt \\\n  --public-ip-address \"\" \\\n  --public-ip-address-allocation static \\\n  --public-ip-address-dns-name \"$DNS_NAME\" \\\n  --lb-sku \"Standard\"\n<\/code><\/pre>\n\n\n\n<p>Notes:\n&#8211; If <code>Standard_B1s<\/code> is not available in your region\/subscription, pick another small SKU available to you (list SKUs with <code>az vm list-skus<\/code>).\n&#8211; The command intentionally keeps the fleet small.<\/p>\n\n\n\n<p><strong>Expected outcome<\/strong>: VMSS is created with 2 instances and an internet-facing endpoint.<\/p>\n\n\n\n<p>Verify VMSS provisioning:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az vmss show -g \"$RG\" -n \"$VMSS\" --query \"{name:name, location:location, sku:sku.name, capacity:sku.capacity}\" -o table\n<\/code><\/pre>\n\n\n\n<p>List instances:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az vmss list-instances -g \"$RG\" -n \"$VMSS\" -o table\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Test the web endpoint<\/h3>\n\n\n\n<p>Get the public IP \/ FQDN:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az network public-ip list -g \"$RG\" --query \"[].{name:name, ipAddress:ipAddress, fqdn:dnsSettings.fqdn}\" -o table\n<\/code><\/pre>\n\n\n\n<p>Then test HTTP (use the FQDN from output):<\/p>\n\n\n\n<pre><code class=\"language-bash\">export FQDN=$(az network public-ip list -g \"$RG\" --query \"[0].dnsSettings.fqdn\" -o tsv)\ncurl -s \"http:\/\/$FQDN\" | head\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome<\/strong>: You receive an HTML page saying \u201cHello from Azure Virtual Machine Scale Sets\u201d and the hostname.<\/p>\n\n\n\n<p>To see load distribution, run a few requests:<\/p>\n\n\n\n<pre><code class=\"language-bash\">for i in {1..10}; do\n  curl -s \"http:\/\/$FQDN\" | grep Hostname\ndone\n<\/code><\/pre>\n\n\n\n<p>You should see hostnames from different instances (not guaranteed every time, depending on connection reuse and LB behavior).<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Configure autoscale rules (CPU-based)<\/h3>\n\n\n\n<p>Create an autoscale setting targeting the VMSS:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az monitor autoscale create \\\n  --resource-group \"$RG\" \\\n  --resource \"\/subscriptions\/$(az account show --query id -o tsv)\/resourceGroups\/$RG\/providers\/Microsoft.Compute\/virtualMachineScaleSets\/$VMSS\" \\\n  --name \"as-$VMSS\" \\\n  --min-count 2 \\\n  --max-count 5 \\\n  --count 2\n<\/code><\/pre>\n\n\n\n<p>Add a rule to <strong>scale out<\/strong> when average CPU is high:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az monitor autoscale rule create \\\n  --resource-group \"$RG\" \\\n  --autoscale-name \"as-$VMSS\" \\\n  --condition \"Percentage CPU &gt; 70 avg 5m\" \\\n  --scale out 1\n<\/code><\/pre>\n\n\n\n<p>Add a rule to <strong>scale in<\/strong> when average CPU is low:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az monitor autoscale rule create \\\n  --resource-group \"$RG\" \\\n  --autoscale-name \"as-$VMSS\" \\\n  --condition \"Percentage CPU &lt; 30 avg 10m\" \\\n  --scale in 1\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome<\/strong>: Autoscale configuration exists and will adjust capacity between 2 and 5.<\/p>\n\n\n\n<p>Verify autoscale configuration:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az monitor autoscale show -g \"$RG\" -n \"as-$VMSS\" --query \"{name:name, enabled:enabled, profiles:profiles[].capacity}\" -o json\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 6 (Optional): Generate CPU load to observe scaling<\/h3>\n\n\n\n<p>To trigger scaling, you can run a short CPU stress test on each instance using VMSS Run Command.<\/p>\n\n\n\n<p>List instance IDs:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az vmss list-instances -g \"$RG\" -n \"$VMSS\" --query \"[].instanceId\" -o tsv\n<\/code><\/pre>\n\n\n\n<p>Run stress on each instance (this can take a few minutes):<\/p>\n\n\n\n<pre><code class=\"language-bash\">for id in $(az vmss list-instances -g \"$RG\" -n \"$VMSS\" --query \"[].instanceId\" -o tsv); do\n  az vmss run-command invoke \\\n    -g \"$RG\" -n \"$VMSS\" \\\n    --instance-id \"$id\" \\\n    --command-id RunShellScript \\\n    --scripts \"sudo apt-get update &amp;&amp; sudo apt-get -y install stress-ng &amp;&amp; stress-ng --cpu 2 --timeout 300s\" \\\n    --query \"value[0].message\" -o tsv\ndone\n<\/code><\/pre>\n\n\n\n<p>Then periodically check instance count:<\/p>\n\n\n\n<pre><code class=\"language-bash\">watch -n 20 \"az vmss show -g $RG -n $VMSS --query sku.capacity -o tsv\"\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome<\/strong>: After several minutes (autoscale evaluation periods apply), the instance count may increase. Scaling is not instantaneous.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Validation<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\n<p><strong>VMSS exists and has instances<\/strong>\n<code>bash\n   az vmss list-instances -g \"$RG\" -n \"$VMSS\" -o table<\/code><\/p>\n<\/li>\n<li>\n<p><strong>Web endpoint works<\/strong>\n<code>bash\n   curl -I \"http:\/\/$FQDN\"<\/code><\/p>\n<\/li>\n<li>\n<p><strong>Autoscale is configured<\/strong>\n<code>bash\n   az monitor autoscale show -g \"$RG\" -n \"as-$VMSS\" -o table<\/code><\/p>\n<\/li>\n<li>\n<p><strong>(Optional) Observe scaling events<\/strong>\n   &#8211; In Azure Portal: VMSS \u2192 <strong>Scaling<\/strong> \/ <strong>Insights<\/strong>\n   &#8211; In Azure Monitor: check metrics for CPU and capacity<\/p>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Troubleshooting<\/h3>\n\n\n\n<p>Common issues and fixes:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\n<p><strong>DNS name not unique<\/strong>\n   &#8211; Error: conflict on public IP DNS label.\n   &#8211; Fix: change <code>DNS_NAME<\/code> and re-run create.<\/p>\n<\/li>\n<li>\n<p><strong>VM SKU not available \/ quota exceeded<\/strong>\n   &#8211; Error: \u201cSKU not available\u201d or \u201cOperation could not be completed as it results in exceeding approved Total Regional Cores quota\u201d.\n   &#8211; Fix:<\/p>\n<ul>\n<li>Choose a different SKU or region.<\/li>\n<li>Request quota increase in Azure Portal (Subscription \u2192 Usage + quotas).<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>Can\u2019t reach the website<\/strong>\n   &#8211; Causes:<\/p>\n<ul>\n<li>NGINX install failed<\/li>\n<li>NSG missing inbound 80 rule<\/li>\n<li>Load balancer rule\/probe misconfigured (if you built custom LB)<\/li>\n<li>Fix:<\/li>\n<li>Check VMSS instance boot output\/logs (cloud-init logs on Ubuntu: <code>\/var\/log\/cloud-init.log<\/code>)<\/li>\n<li>Use Run Command to inspect:\n   <code>bash\n   az vmss run-command invoke -g \"$RG\" -n \"$VMSS\" --instance-id 0 \\\n     --command-id RunShellScript --scripts \"systemctl status nginx --no-pager; curl -I http:\/\/localhost\"<\/code><\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>Autoscale not triggering<\/strong>\n   &#8211; Reasons:<\/p>\n<ul>\n<li>CPU not high enough long enough<\/li>\n<li>cooldown periods \/ evaluation windows not met<\/li>\n<li>Metric collection delays<\/li>\n<li>Fix:<\/li>\n<li>Wait longer, increase stress duration, or adjust thresholds conservatively.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Cleanup<\/h3>\n\n\n\n<p>Delete the resource group to remove <strong>all<\/strong> lab resources:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az group delete --name \"$RG\" --yes --no-wait\n<\/code><\/pre>\n\n\n\n<p>Verify deletion (optional):<\/p>\n\n\n\n<pre><code class=\"language-bash\">az group exists --name \"$RG\"\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">11. Best Practices<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Architecture best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Put VMSS instances behind <strong>Load Balancer<\/strong> (L4) or <strong>Application Gateway<\/strong> (L7) to avoid direct exposure.<\/li>\n<li>Prefer <strong>stateless<\/strong> designs:<\/li>\n<li>Store session state in Redis\/cache<\/li>\n<li>Store files in Azure Storage<\/li>\n<li>Store data in managed databases<\/li>\n<li>Use <strong>Availability Zones<\/strong> for higher resiliency where supported.<\/li>\n<li>Consider multi-region for critical workloads (Front Door + separate regional stacks).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">IAM\/security best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use <strong>least privilege<\/strong> RBAC:<\/li>\n<li>Separate roles for deployers vs operators vs auditors<\/li>\n<li>Use <strong>Managed Identity<\/strong> for VMSS to access Key Vault\/Storage without secrets in code.<\/li>\n<li>Avoid opening SSH\/RDP to the internet; use:<\/li>\n<li>Azure Bastion<\/li>\n<li>Just-in-time (JIT) access (Defender for Cloud, where applicable)<\/li>\n<li>Private connectivity + jump host<\/li>\n<li>Use Azure Policy to enforce:<\/li>\n<li>Approved VM SKUs\/images<\/li>\n<li>Required tags<\/li>\n<li>Disk encryption settings (where applicable)<\/li>\n<li>No public IPs on NICs (common requirement)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Cost best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Set autoscale <strong>minimum<\/strong> to what you truly need for baseline availability.<\/li>\n<li>Use <strong>scheduled autoscale<\/strong> for predictable patterns.<\/li>\n<li>Consider <strong>Spot VMSS<\/strong> for interruptible compute pools.<\/li>\n<li>Right-size disks and limit Log Analytics ingestion\/retention.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Performance best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Choose VM SKUs based on CPU\/memory\/network needs; validate with load testing.<\/li>\n<li>Ensure your load balancer health probes match application readiness.<\/li>\n<li>Use connection pooling wisely; avoid long-lived connections if they cause uneven load distribution.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Reliability best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Design for instance replacement:<\/li>\n<li>Instances can be reimaged or replaced during updates or failures.<\/li>\n<li>Use health probes and (where supported) application health reporting.<\/li>\n<li>Use rolling deployments and keep enough capacity during upgrades.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Operations best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Standardize images through <strong>Azure Compute Gallery<\/strong> and a CI pipeline.<\/li>\n<li>Implement patch strategy:<\/li>\n<li>Image-based patching or update management (verify current Azure offerings and your org requirements).<\/li>\n<li>Capture logs\/metrics centrally and define SLO-based alerts (latency, error rate, saturation).<\/li>\n<li>Use tags for ownership, environment, cost center, and data classification.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Governance\/tagging\/naming best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Naming:<\/li>\n<li><code>vmss-&lt;app&gt;-&lt;env&gt;-&lt;region&gt;<\/code><\/li>\n<li>Tags (minimum):<\/li>\n<li><code>env<\/code>, <code>owner<\/code>, <code>costCenter<\/code>, <code>app<\/code>, <code>dataClass<\/code>, <code>lifecycle<\/code><\/li>\n<li>Lock critical production resource groups where appropriate (with clear change processes).<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">12. Security Considerations<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Identity and access model<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Azure RBAC<\/strong> controls management operations on VMSS and related resources.<\/li>\n<li>Use <strong>Managed Identity<\/strong> (system-assigned or user-assigned) for:<\/li>\n<li>Key Vault secret retrieval<\/li>\n<li>Storage access<\/li>\n<li>Metric publishing (custom patterns)<\/li>\n<li>Avoid embedding credentials in:<\/li>\n<li>custom-data<\/li>\n<li>scripts<\/li>\n<li>VM images<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Encryption<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Data at rest:<\/li>\n<li>Managed disks support server-side encryption by default (details depend on configuration\u2014verify).<\/li>\n<li>For stricter requirements, evaluate customer-managed keys (CMK) and disk encryption options.<\/li>\n<li>Data in transit:<\/li>\n<li>Use TLS end-to-end for HTTP apps.<\/li>\n<li>Terminate TLS at Application Gateway\/Front Door when appropriate and re-encrypt to backends if needed.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Network exposure<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Prefer <strong>no public IPs on instances<\/strong>.<\/li>\n<li>Restrict inbound traffic with NSGs:<\/li>\n<li>allow only from load balancer\/app gateway subnets<\/li>\n<li>deny all other inbound<\/li>\n<li>Control outbound:<\/li>\n<li>NAT Gateway or Azure Firewall for consistent egress and logging<\/li>\n<li>private endpoints for PaaS dependencies<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Secrets handling<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use Key Vault + Managed Identity.<\/li>\n<li>Rotate secrets and certificates.<\/li>\n<li>Use short-lived credentials where feasible.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Audit\/logging<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use Azure Activity Log for control-plane auditing.<\/li>\n<li>Enable diagnostic settings for relevant resources (Load Balancer, Application Gateway, Key Vault).<\/li>\n<li>Centralize logs in Log Analytics or a SIEM (Microsoft Sentinel) based on your org policy.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Compliance considerations<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Data residency: keep compute and data in approved regions.<\/li>\n<li>Use Azure Policy and Blueprints-like patterns (Azure Policy initiatives) to enforce controls.<\/li>\n<li>Maintain patching, vulnerability scanning, and baseline hardening documentation.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Common security mistakes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Exposing SSH\/RDP to <code>0.0.0.0\/0<\/code><\/li>\n<li>Storing secrets in cloud-init\/custom scripts<\/li>\n<li>No egress control (data exfil risk)<\/li>\n<li>Over-permissive RBAC (e.g., everyone is Owner)<\/li>\n<li>Lack of logging\/retention strategy (either none, or excessive cost)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Secure deployment recommendations<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Private subnet + load balancer\/app gateway in a controlled DMZ.<\/li>\n<li>Managed Identity + Key Vault references.<\/li>\n<li>Explicit outbound path (NAT Gateway\/Firewall) and private endpoints to dependencies.<\/li>\n<li>Regular image rebuild pipeline (patched golden images).<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">13. Limitations and Gotchas<\/h2>\n\n\n\n<blockquote>\n<p>Limits and behaviors change over time and vary by orchestration mode and region. Verify in official docs for your chosen mode and SKU.<\/p>\n<\/blockquote>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Orchestration mode differences<\/strong>: Uniform and Flexible do not offer identical feature sets.<\/li>\n<li><strong>Quota constraints<\/strong>: Regional vCPU quotas are the most common deployment blocker.<\/li>\n<li><strong>SKU availability<\/strong>: Some VM sizes (GPU, memory optimized) are not in all regions.<\/li>\n<li><strong>Scaling is not instantaneous<\/strong>: Provisioning new VMs can take minutes, especially with many extensions.<\/li>\n<li><strong>Health probe pitfalls<\/strong>: Misconfigured probes can route traffic to unhealthy instances or cause unnecessary replacements.<\/li>\n<li><strong>Statefulness issues<\/strong>: Local state disappears when instances are replaced; design for statelessness.<\/li>\n<li><strong>Outbound networking surprises<\/strong>: Default SNAT\/outbound behavior can cause port exhaustion or unpredictable egress IPs; use explicit egress architecture for production.<\/li>\n<li><strong>Logging costs<\/strong>: High-volume logs to Log Analytics can become a major cost driver.<\/li>\n<li><strong>Image rollout discipline<\/strong>: Updating images without a rollout plan can cause fleet-wide regressions.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">14. Comparison with Alternatives<\/h2>\n\n\n\n<p>Virtual Machine Scale Sets is one option in Azure Compute. Here\u2019s how it compares to common alternatives in Azure and other clouds.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Option<\/th>\n<th>Best For<\/th>\n<th>Strengths<\/th>\n<th>Weaknesses<\/th>\n<th>When to Choose<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Azure Virtual Machine Scale Sets<\/strong><\/td>\n<td>VM fleets needing autoscale and centralized management<\/td>\n<td>VM-level control + scaling + LB integration<\/td>\n<td>More ops than PaaS; patching\/image mgmt is on you<\/td>\n<td>When you need VM access, custom OS deps, or lift-and-improve<\/td>\n<\/tr>\n<tr>\n<td><strong>Azure Virtual Machines (single VMs)<\/strong><\/td>\n<td>Single server workloads<\/td>\n<td>Simple, direct<\/td>\n<td>No fleet management; manual scaling<\/td>\n<td>When you only need 1\u20132 servers or special snowflake workloads<\/td>\n<\/tr>\n<tr>\n<td><strong>Azure App Service<\/strong><\/td>\n<td>Web apps\/APIs with minimal infra management<\/td>\n<td>PaaS simplicity, fast deploy, built-in scaling options<\/td>\n<td>Less OS control; platform constraints<\/td>\n<td>When your app fits the supported runtimes and you want less ops<\/td>\n<\/tr>\n<tr>\n<td><strong>Azure Kubernetes Service (AKS)<\/strong><\/td>\n<td>Container orchestration at scale<\/td>\n<td>Powerful scheduling, rolling deploys, service mesh ecosystem<\/td>\n<td>Complexity, cluster operations<\/td>\n<td>When you are container-native and need Kubernetes capabilities<\/td>\n<\/tr>\n<tr>\n<td><strong>Azure Functions<\/strong><\/td>\n<td>Event-driven serverless compute<\/td>\n<td>Scale-to-zero, pay-per-execution patterns<\/td>\n<td>Runtime constraints, cold starts<\/td>\n<td>For event-driven workloads and bursty execution<\/td>\n<\/tr>\n<tr>\n<td><strong>Azure Container Apps<\/strong><\/td>\n<td>Managed containers without full Kubernetes ops<\/td>\n<td>Simpler than AKS, autoscaling incl. KEDA patterns<\/td>\n<td>Platform constraints, still evolving features<\/td>\n<td>When you want containers + scaling with minimal cluster management<\/td>\n<\/tr>\n<tr>\n<td><strong>AWS Auto Scaling Groups (EC2)<\/strong><\/td>\n<td>AWS VM fleets<\/td>\n<td>Mature autoscaling for EC2<\/td>\n<td>Different ecosystem; migration effort<\/td>\n<td>Choose when workload is on AWS<\/td>\n<\/tr>\n<tr>\n<td><strong>Google Managed Instance Groups (MIG)<\/strong><\/td>\n<td>GCP VM fleets<\/td>\n<td>Strong VM fleet patterns<\/td>\n<td>Different ecosystem<\/td>\n<td>Choose when workload is on GCP<\/td>\n<\/tr>\n<tr>\n<td><strong>Self-managed (VMs + scripts)<\/strong><\/td>\n<td>Small fleets, bespoke needs<\/td>\n<td>Maximum control<\/td>\n<td>High toil and risk<\/td>\n<td>Only when tooling constraints require it<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">15. Real-World Example<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Enterprise example: Zonal web\/API tier with compliance controls<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem<\/strong>: A regulated enterprise needs a scalable API tier with tight network controls, auditability, and predictable rollouts.<\/li>\n<li><strong>Proposed architecture<\/strong>:<\/li>\n<li>Azure Front Door (global entry) \u2192 Application Gateway WAF (regional) \u2192 VMSS (zonal) in private subnet<\/li>\n<li>Private endpoints to Key Vault, Storage, and Azure SQL<\/li>\n<li>Azure Monitor + Log Analytics + alerting; Activity Log retention to centralized logging<\/li>\n<li>Golden images stored in Azure Compute Gallery; deployments via CI\/CD<\/li>\n<li><strong>Why VMSS was chosen<\/strong>:<\/li>\n<li>VM-level control required for custom agents and hardened baselines<\/li>\n<li>Autoscale supports variable demand<\/li>\n<li>Fits hub-and-spoke network governance<\/li>\n<li><strong>Expected outcomes<\/strong>:<\/li>\n<li>Reduced operational overhead vs individual VMs<\/li>\n<li>Improved resiliency across zones<\/li>\n<li>Standardized patching via image pipeline and controlled rollouts<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Startup\/small-team example: Cost-controlled API service<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem<\/strong>: A startup needs a scalable API with predictable costs and simple operations, but requires VM-level control for a specialized dependency.<\/li>\n<li><strong>Proposed architecture<\/strong>:<\/li>\n<li>Standard Load Balancer + VMSS with 2\u20136 instances<\/li>\n<li>Azure Database for PostgreSQL (managed) for persistence<\/li>\n<li>Autoscale based on CPU; scheduled scale-in at night<\/li>\n<li>Minimal logging with targeted metrics and alerts<\/li>\n<li><strong>Why VMSS was chosen<\/strong>:<\/li>\n<li>App Service wasn\u2019t suitable due to OS-level dependency<\/li>\n<li>VMSS offers autoscale without building custom orchestration<\/li>\n<li><strong>Expected outcomes<\/strong>:<\/li>\n<li>Meets demand spikes without constant overprovisioning<\/li>\n<li>Small baseline cost with growth path<\/li>\n<li>Simple \u201cone resource\u201d compute fleet management<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">16. FAQ<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\n<p><strong>Is Virtual Machine Scale Sets a PaaS service?<\/strong><br\/>\n   No. VMSS is an <strong>IaaS fleet orchestration<\/strong> service for Azure Virtual Machines. You still manage OS\/application configuration (often via images and automation).<\/p>\n<\/li>\n<li>\n<p><strong>Do I pay extra for VMSS itself?<\/strong><br\/>\n   Typically, <strong>no separate VMSS fee<\/strong>\u2014you pay for VMs, disks, networking, and monitoring resources you deploy.<\/p>\n<\/li>\n<li>\n<p><strong>What\u2019s the difference between Uniform and Flexible orchestration?<\/strong><br\/>\n   They represent different ways Azure manages instances and features. The best choice depends on upgrade behavior, VM feature parity needs, and operational model. <strong>Verify the latest capability matrix in official docs<\/strong> because details evolve.<\/p>\n<\/li>\n<li>\n<p><strong>Can VMSS scale to zero?<\/strong><br\/>\n   Some designs allow scaling very low, but whether \u201czero\u201d is appropriate depends on your inbound traffic model and architecture. For always-on endpoints, you usually keep at least 1\u20132 instances.<\/p>\n<\/li>\n<li>\n<p><strong>How does autoscale decide when to add instances?<\/strong><br\/>\n   Autoscale uses Azure Monitor metrics and rules (thresholds and time windows). There can be a delay due to metric aggregation and VM provisioning time.<\/p>\n<\/li>\n<li>\n<p><strong>Do VMSS instances need public IPs?<\/strong><br\/>\n   Usually <strong>no<\/strong>. Best practice is to put instances in a private subnet and expose only a load balancer\/application gateway.<\/p>\n<\/li>\n<li>\n<p><strong>How do I deploy application code to VMSS instances?<\/strong><br\/>\n   Common patterns:\n   &#8211; Bake a golden VM image (Compute Gallery)\n   &#8211; Use cloud-init or VM extensions to pull artifacts at boot\n   &#8211; Use a configuration management tool (Ansible\/Chef\/Puppet)<br\/>\n   For large fleets, image-based is often more consistent.<\/p>\n<\/li>\n<li>\n<p><strong>How do rolling upgrades work?<\/strong><br\/>\n   Rolling upgrades update instances gradually based on policy (mode-dependent). You aim to keep enough healthy capacity while updating. <strong>Verify exact behavior in your orchestration mode<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>Can I use a custom image?<\/strong><br\/>\n   Yes. VMSS supports marketplace images and custom images; Azure Compute Gallery is a common enterprise approach for versioned images.<\/p>\n<\/li>\n<li>\n<p><strong>How do I monitor VMSS health?<\/strong><br\/>\n   Use:\n   &#8211; Load balancer\/application gateway health probes\n   &#8211; Azure Monitor metrics (CPU, network, disk)\n   &#8211; Guest OS logs via Azure Monitor Agent to Log Analytics<\/p>\n<\/li>\n<li>\n<p><strong>What happens if an instance is unhealthy?<\/strong><br\/>\n   It may be removed from load balancer rotation (probe failure). Depending on configuration, the platform may also repair\/replace instances (capability varies\u2014verify).<\/p>\n<\/li>\n<li>\n<p><strong>Is VMSS suitable for stateful workloads?<\/strong><br\/>\n   It\u2019s best for <strong>stateless<\/strong> workloads. Stateful workloads require careful design (externalized state, durable storage, controlled instance replacement).<\/p>\n<\/li>\n<li>\n<p><strong>Can VMSS run Windows Server?<\/strong><br\/>\n   Yes, VMSS supports Windows and Linux images (licensing and pricing differ).<\/p>\n<\/li>\n<li>\n<p><strong>How do I control outbound IP addresses?<\/strong><br\/>\n   Use explicit egress architecture such as <strong>NAT Gateway<\/strong> or <strong>Azure Firewall<\/strong> depending on requirements. Avoid relying on defaults for production.<\/p>\n<\/li>\n<li>\n<p><strong>What\u2019s the simplest way to get started?<\/strong><br\/>\n   Use Azure CLI <code>az vmss create<\/code> to deploy a small scale set behind a standard load balancer, then add autoscale rules and basic monitoring.<\/p>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">17. Top Online Resources to Learn Virtual Machine Scale Sets<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Resource Type<\/th>\n<th>Name<\/th>\n<th>Why It Is Useful<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Official documentation<\/td>\n<td>Virtual Machine Scale Sets documentation (Learn) \u2013 https:\/\/learn.microsoft.com\/azure\/virtual-machine-scale-sets\/<\/td>\n<td>Canonical docs: concepts, orchestration modes, scaling, upgrades<\/td>\n<\/tr>\n<tr>\n<td>Official quickstarts<\/td>\n<td>Search VMSS quickstarts on Learn \u2013 https:\/\/learn.microsoft.com\/azure\/virtual-machine-scale-sets\/<\/td>\n<td>Step-by-step deployment guides and examples<\/td>\n<\/tr>\n<tr>\n<td>Official pricing<\/td>\n<td>Azure Virtual Machines pricing \u2013 https:\/\/azure.microsoft.com\/pricing\/details\/virtual-machines\/<\/td>\n<td>VM compute pricing (main cost component)<\/td>\n<\/tr>\n<tr>\n<td>Official pricing<\/td>\n<td>Azure Load Balancer pricing \u2013 https:\/\/azure.microsoft.com\/pricing\/details\/load-balancer\/<\/td>\n<td>Understand LB SKU cost implications<\/td>\n<\/tr>\n<tr>\n<td>Official pricing<\/td>\n<td>Azure Managed Disks pricing \u2013 https:\/\/azure.microsoft.com\/pricing\/details\/managed-disks\/<\/td>\n<td>Disk tier\/size cost planning<\/td>\n<\/tr>\n<tr>\n<td>Official pricing<\/td>\n<td>Azure Monitor pricing \u2013 https:\/\/azure.microsoft.com\/pricing\/details\/monitor\/<\/td>\n<td>Log ingestion\/retention cost planning<\/td>\n<\/tr>\n<tr>\n<td>Official tool<\/td>\n<td>Azure Pricing Calculator \u2013 https:\/\/azure.microsoft.com\/pricing\/calculator\/<\/td>\n<td>Build region\/SKU-specific estimates<\/td>\n<\/tr>\n<tr>\n<td>Architecture guidance<\/td>\n<td>Azure Architecture Center \u2013 https:\/\/learn.microsoft.com\/azure\/architecture\/<\/td>\n<td>Reference architectures and best practices for scalable designs<\/td>\n<\/tr>\n<tr>\n<td>CLI reference<\/td>\n<td><code>az vmss<\/code> command group \u2013 https:\/\/learn.microsoft.com\/cli\/azure\/vmss<\/td>\n<td>Up-to-date CLI syntax for scripting deployments<\/td>\n<\/tr>\n<tr>\n<td>Samples<\/td>\n<td>Azure Quickstart Templates (ARM) \u2013 https:\/\/github.com\/Azure\/azure-quickstart-templates<\/td>\n<td>Many infrastructure patterns include VMSS examples (verify template currency)<\/td>\n<\/tr>\n<tr>\n<td>Videos<\/td>\n<td>Microsoft Azure YouTube \u2013 https:\/\/www.youtube.com\/@MicrosoftAzure<\/td>\n<td>Product walkthroughs; verify recency of specific VMSS content<\/td>\n<\/tr>\n<tr>\n<td>Community learning<\/td>\n<td>Microsoft Q&amp;A (Azure) \u2013 https:\/\/learn.microsoft.com\/answers\/topics\/azure-virtual-machines.html<\/td>\n<td>Real troubleshooting threads; validate answers against docs<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">18. Training and Certification Providers<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Institute<\/th>\n<th>Suitable Audience<\/th>\n<th>Likely Learning Focus<\/th>\n<th>Mode<\/th>\n<th>Website URL<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>DevOpsSchool.com<\/td>\n<td>DevOps engineers, SREs, platform teams<\/td>\n<td>Azure DevOps, infrastructure automation, operational practices<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.devopsschool.com\/<\/td>\n<\/tr>\n<tr>\n<td>ScmGalaxy.com<\/td>\n<td>Beginners to intermediate engineers<\/td>\n<td>DevOps fundamentals, tools, CI\/CD concepts<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.scmgalaxy.com\/<\/td>\n<\/tr>\n<tr>\n<td>CLoudOpsNow.in<\/td>\n<td>Cloud engineers, operations teams<\/td>\n<td>Cloud operations, monitoring, reliability practices<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.cloudopsnow.in\/<\/td>\n<\/tr>\n<tr>\n<td>SreSchool.com<\/td>\n<td>SREs, platform engineers<\/td>\n<td>SRE principles, incident response, observability<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.sreschool.com\/<\/td>\n<\/tr>\n<tr>\n<td>AiOpsSchool.com<\/td>\n<td>Ops\/SRE teams exploring AIOps<\/td>\n<td>AIOps concepts, monitoring automation, operations analytics<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.aiopsschool.com\/<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">19. Top Trainers<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Platform\/Site<\/th>\n<th>Likely Specialization<\/th>\n<th>Suitable Audience<\/th>\n<th>Website URL<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>RajeshKumar.xyz<\/td>\n<td>Cloud\/DevOps training content (verify offerings)<\/td>\n<td>Beginners to intermediate<\/td>\n<td>https:\/\/www.rajeshkumar.xyz\/<\/td>\n<\/tr>\n<tr>\n<td>devopstrainer.in<\/td>\n<td>DevOps training (tools + cloud)<\/td>\n<td>DevOps engineers, students<\/td>\n<td>https:\/\/www.devopstrainer.in\/<\/td>\n<\/tr>\n<tr>\n<td>devopsfreelancer.com<\/td>\n<td>Freelance DevOps consulting\/training platform (verify services)<\/td>\n<td>Teams seeking short-term expertise<\/td>\n<td>https:\/\/www.devopsfreelancer.com\/<\/td>\n<\/tr>\n<tr>\n<td>devopssupport.in<\/td>\n<td>DevOps support and training resources (verify services)<\/td>\n<td>Ops teams needing troubleshooting help<\/td>\n<td>https:\/\/www.devopssupport.in\/<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">20. Top Consulting Companies<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Company Name<\/th>\n<th>Likely Service Area<\/th>\n<th>Where They May Help<\/th>\n<th>Consulting Use Case Examples<\/th>\n<th>Website URL<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>cotocus.com<\/td>\n<td>Cloud\/DevOps consulting (verify offerings)<\/td>\n<td>Architecture, automation, deployments<\/td>\n<td>VMSS landing zones, autoscale setups, monitoring baselines<\/td>\n<td>https:\/\/cotocus.com\/<\/td>\n<\/tr>\n<tr>\n<td>DevOpsSchool.com<\/td>\n<td>DevOps and cloud consulting\/training<\/td>\n<td>Delivery enablement, DevOps transformation<\/td>\n<td>CI\/CD + image pipelines, VMSS operational runbooks<\/td>\n<td>https:\/\/www.devopsschool.com\/<\/td>\n<\/tr>\n<tr>\n<td>DEVOPSCONSULTING.IN<\/td>\n<td>DevOps consulting (verify offerings)<\/td>\n<td>Toolchain integration, infrastructure automation<\/td>\n<td>IaC standardization, security hardening, cost optimization reviews<\/td>\n<td>https:\/\/www.devopsconsulting.in\/<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">21. Career and Learning Roadmap<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What to learn before Virtual Machine Scale Sets<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Azure fundamentals:<\/li>\n<li>subscriptions, resource groups, regions<\/li>\n<li>Azure RBAC and Entra ID basics<\/li>\n<li>Azure networking:<\/li>\n<li>VNets, subnets, NSGs, routing<\/li>\n<li>Load Balancer basics and health probes<\/li>\n<li>Virtual machine basics:<\/li>\n<li>Linux\/Windows administration fundamentals<\/li>\n<li>SSH keys, package management<\/li>\n<li>Infrastructure as Code basics:<\/li>\n<li>ARM\/Bicep or Terraform fundamentals<\/li>\n<li>Monitoring basics:<\/li>\n<li>metrics vs logs, alerts, dashboards<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">What to learn after Virtual Machine Scale Sets<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Image pipelines:<\/li>\n<li>Azure Compute Gallery<\/li>\n<li>Packer-based image builds (common pattern)<\/li>\n<li>Advanced routing and security:<\/li>\n<li>Application Gateway (WAF), Front Door<\/li>\n<li>Private endpoints, NAT Gateway, Azure Firewall<\/li>\n<li>Operational excellence:<\/li>\n<li>SRE practices: SLOs, error budgets, incident management<\/li>\n<li>Azure Monitor at scale, Log Analytics cost management<\/li>\n<li>Modernization paths:<\/li>\n<li>AKS (if moving to containers)<\/li>\n<li>App Service \/ Container Apps (if moving to PaaS)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Job roles that use VMSS<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Cloud engineer \/ cloud infrastructure engineer<\/li>\n<li>DevOps engineer<\/li>\n<li>Site Reliability Engineer (SRE)<\/li>\n<li>Platform engineer<\/li>\n<li>Solutions architect (designing scalable compute tiers)<\/li>\n<li>Security engineer (hardening and governance patterns)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Certification path (Azure)<\/h3>\n\n\n\n<p>Depending on your goals, consider Microsoft certifications that cover Azure compute\/networking\/operations. Start with:\n&#8211; <strong>AZ-900 (Azure Fundamentals)<\/strong> for baseline concepts\n&#8211; Role-based certifications (administrator\/architect\/devops) depending on your track<br\/>\nVerify current certification names and objectives here: https:\/\/learn.microsoft.com\/credentials\/<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Project ideas for practice<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Build a VMSS-based web tier with:<\/li>\n<li>autoscale rules<\/li>\n<li>rolling upgrades via new image versions<\/li>\n<li>blue\/green deployment using two scale sets behind Application Gateway<\/li>\n<li>Create a queue worker VMSS:<\/li>\n<li>poll Azure Service Bus<\/li>\n<li>scale based on custom metric (verify approach)<\/li>\n<li>Secure VMSS design:<\/li>\n<li>private subnet<\/li>\n<li>Key Vault secrets via Managed Identity<\/li>\n<li>private endpoints for Storage\/SQL<\/li>\n<li>centralized egress through NAT Gateway\/Firewall<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">22. Glossary<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>VMSS (Virtual Machine Scale Sets)<\/strong>: Azure service for managing and scaling a group of VMs as one unit.<\/li>\n<li><strong>Instance<\/strong>: A single VM created as part of a scale set.<\/li>\n<li><strong>Autoscale<\/strong>: Automatic adjustment of instance count based on metrics or schedules.<\/li>\n<li><strong>Azure Monitor<\/strong>: Platform service for metrics, logs, alerting, and autoscale settings.<\/li>\n<li><strong>Health probe<\/strong>: A periodic check (e.g., HTTP\/TCP) used by a load balancer\/application gateway to decide if an instance should receive traffic.<\/li>\n<li><strong>Azure Load Balancer<\/strong>: Layer 4 load balancer (TCP\/UDP) often used with VMSS.<\/li>\n<li><strong>Azure Application Gateway<\/strong>: Layer 7 HTTP(S) load balancer with routing features; can include WAF.<\/li>\n<li><strong>Availability Zone<\/strong>: Physically separate datacenter locations within an Azure region.<\/li>\n<li><strong>Azure Compute Gallery<\/strong>: Service for managing and sharing custom VM images (official name; formerly Shared Image Gallery).<\/li>\n<li><strong>Managed Disk<\/strong>: Azure-managed block storage for VM OS and data disks.<\/li>\n<li><strong>NSG (Network Security Group)<\/strong>: Stateful firewall rules for subnets\/NICs.<\/li>\n<li><strong>Managed Identity<\/strong>: Azure identity for a resource to authenticate to other Azure services without storing credentials.<\/li>\n<li><strong>Golden image<\/strong>: A prebuilt VM image containing OS patches and required software, used to create consistent instances.<\/li>\n<li><strong>Egress<\/strong>: Outbound network traffic from Azure to the internet or other destinations (often billable).<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">23. Summary<\/h2>\n\n\n\n<p>Azure <strong>Virtual Machine Scale Sets<\/strong> is a Compute service for running <strong>scalable VM fleets<\/strong> with centralized configuration, health-aware load balancing integration, and <strong>autoscaling<\/strong> through Azure Monitor. It fits best when you need VM-level control (custom OS dependencies, agents, legacy software) while still wanting modern cloud patterns like horizontal scaling and automated instance management.<\/p>\n\n\n\n<p>Cost is primarily driven by <strong>VM compute<\/strong>, <strong>disks<\/strong>, <strong>networking (load balancer\/public IP\/egress)<\/strong>, and <strong>monitoring logs<\/strong>\u2014not by VMSS itself as a separate line item. Security success depends on avoiding public management exposure, using <strong>Managed Identity<\/strong>, controlling egress, and standardizing hardened images with strong governance.<\/p>\n\n\n\n<p>Use VMSS for stateless web\/API tiers, worker pools, CI agents, and batch compute where instance replacement is acceptable. If you want less infrastructure management, evaluate Azure PaaS options; if you\u2019re container-native at scale, evaluate AKS or Container Apps.<\/p>\n\n\n\n<p>Next step: extend the lab by introducing a <strong>custom image pipeline<\/strong> (Azure Compute Gallery) and implementing a <strong>blue\/green deployment<\/strong> with two scale sets and controlled traffic shifting.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Compute<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[40,26],"tags":[],"class_list":["post-395","post","type-post","status-publish","format-standard","hentry","category-azure","category-compute"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/395","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/comments?post=395"}],"version-history":[{"count":0,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/395\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=395"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=395"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=395"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}