Lesson 11 — Azure App Service
Why App Service Is the Most Exam-Dense PaaS Topic
App Service is Azure's flagship platform-as-a-service compute offering. It covers more exam surface area than any other single PaaS service in the AZ-104 domain: plans, slots, scaling, networking, authentication, certificates, and deployment strategies are all in scope. More importantly, App Service is the default answer for "how do I host a web application in Azure without managing infrastructure" — a question that comes up constantly in real production environments.
The exam tests whether you understand the boundaries between tiers, the mechanics of zero-downtime deploys, and the important distinction between making the app's outbound traffic private (VNet Integration) versus making its inbound endpoint private (Private Endpoints). These are commonly confused and frequently tested.
App Service Overview
Azure App Service is a fully managed HTTP-based hosting platform for web applications, REST APIs, and mobile backends. Azure handles the operating system, runtime patching, load balancing, and hardware provisioning. You bring the code.
Supported runtimes
App Service supports .NET, Node.js, Python, PHP, Java, and Ruby on both Linux and Windows hosting stacks. You can also deploy custom containers (Docker images) to App Service instead of using a built-in runtime stack.
The hosting model
App Service abstracts the compute into a two-layer model: the App Service Plan defines and pays for the compute resources, and one or more App Service apps run on that plan. Multiple apps can share a single plan at no extra compute cost — though they compete for the plan's resources.
App Service Plans — The Tier Decision
The App Service Plan is the billing unit. It defines the region, the number of VM instances, and the size (vCPU/RAM) of those instances. Every app must belong to a plan. Choosing the wrong tier is the most common App Service mistake because critical features like autoscale and deployment slots are tier-gated.
| Tier | Infrastructure | SLA | Autoscale | Deployment Slots | VNet Integration | Key Use Case |
|---|---|---|---|---|---|---|
| Free (F1) | Shared | None | No | No | No | Exploration, learning |
| Shared (D1) | Shared | None | No | No | No | Custom domains on shared infra |
| Basic (B1/B2/B3) | Dedicated VMs | 99.95% | No | No | No | Dev/test, low-traffic apps |
| Standard (S1/S2/S3) | Dedicated VMs | 99.95% | Yes | 5 slots | Yes (regional) | Production web apps |
| Premium v2/v3 (P0v3–P3v3) | Dedicated VMs (faster) | 99.95% | Yes | 20 slots | Yes + private endpoints | High-performance production |
| Isolated v2 (I1v2–I3v2) | Dedicated hosts in your VNet (ASE) | 99.95% | Yes | 20 slots | Full VNet isolation | Compliance, strict isolation |
Deployment Slots
Deployment slots are live, independently addressable copies of your App Service app within the same App Service Plan. They are the mechanism for zero-downtime deployments in Azure App Service.
How slots work
- Each slot has its own URL:
myapp.azurewebsites.net(production) andmyapp-staging.azurewebsites.net(staging). - Slots are fully live — staging can be hit directly by QA teams or smoke tests.
- A swap operation atomically exchanges the content and configuration between two slots. After a swap, staging becomes production and vice versa.
- Swaps are instant from the perspective of clients — no downtime, no connection resets in flight.
- Swaps are reversible: immediately swap back if you discover a problem in production.
Slot-sticky settings
Some app settings and connection strings should not travel with the code when you swap. For example, the production database connection string should always stay in the production slot — you never want staging's DB string to accidentally land in production (or vice versa) after a swap.
Mark a setting as deployment slot setting (sticky) in the App Service Configuration blade. Sticky settings stay with the slot regardless of which code revision is currently deployed there.
Traffic splitting (A/B testing)
You can route a percentage of live traffic to a non-production slot without a full swap. This is configured in the Deployment Slots blade as a traffic percentage. Use this for gradual rollouts (e.g. 5% of traffic → new version) or A/B feature testing with real users.
Slot limits by tier
| Tier | Max Deployment Slots (including production) |
|---|---|
| Free, Shared, Basic | 1 (production only — no staging slots) |
| Standard | 6 (production + 5 staging slots) |
| Premium v2/v3, Isolated v2 | 21 (production + 20 staging slots) |
Deployment Methods
App Service supports several ways to get your code into a slot. Each has different tradeoffs for reliability, speed, and automation:
| Method | Description | Best For |
|---|---|---|
| ZIP Deploy | POST a ZIP of the app to the Kudu REST API. Fast, simple, widely supported. | CI/CD pipelines, scripted deploys |
| Run From Package | Mount a ZIP as a read-only file system. App runs directly from the ZIP — wwwroot is read-only. Recommended method. | Production — eliminates partial deploy state |
| GitHub Actions | Azure provides a starter workflow. Deploys on push to a branch. | GitHub-hosted source repositories |
| Azure DevOps Pipelines | Full CI/CD pipeline with YAML definitions. Native Azure integration. | Enterprise DevOps workflows |
| Local Git / GitHub / GitLab | Push to a Git remote hosted by App Service (Kudu). App Service builds on receive. | Simple projects, demo environments |
| Container Registry | Pull a Docker image from ACR, Docker Hub, or any OCI registry on startup. | Containerised app deployments |
| FTP | Legacy file transfer. Available but not recommended — no atomicity, partial states possible. | Legacy only — avoid in new deployments |
WEBSITE_RUN_FROM_PACKAGE=1 is set, the app mounts the deployment ZIP as a read-only file system. This means: no partial deploys (the ZIP either mounts or it doesn't), consistent disk state across all instances, and faster cold starts because there's no extraction step. The trade-off is that the app cannot write to its own wwwroot directory — use Azure Files or Blob Storage for writable storage needs.
Custom Domains and TLS/SSL Certificates
Adding a custom domain
By default, App Service apps get a free .azurewebsites.net subdomain. To use a custom domain you own:
- Subdomain (e.g.
api.contoso.com): Create a CNAME record pointing tomyapp.azurewebsites.net, then add a TXT record for domain verification. - Apex/root domain (e.g.
contoso.com): Create an A record pointing to the app's inbound IP address, plus a TXT record (awverify) for verification. CNAMEs cannot be used at the zone apex.
Domain ownership is verified via a TXT record before App Service will accept the domain binding.
TLS/SSL certificates
| Certificate Type | Cost | Domains Supported | Auto-Renew | Exportable |
|---|---|---|---|---|
| App Service Managed Certificate | Free | Subdomains only (CNAME-verified) | Yes | No |
| App Service Certificate | Paid (purchased via Azure) | Subdomain or wildcard | Yes | Yes (stored in Key Vault) |
| Third-party / uploaded certificate | Varies | Any (subdomain, wildcard, SAN) | Manual | Yes |
| Certificate from Key Vault | Key Vault pricing | Any | Yes (Key Vault auto-rotate) | Depends on certificate |
contoso.com (no subdomain), use a third-party certificate or an App Service Certificate.
Scaling App Service
Scale up (vertical scaling)
Scale up by moving the App Service Plan to a higher tier — for example, from S1 to S2 or from S3 to P1v3. This gives each instance more vCPU and RAM. Scale-up is a manual operation and requires a brief instance restart.
Scale out (horizontal scaling)
Scale out by increasing the instance count — running multiple identical instances behind App Service's built-in load balancer. Scale-out can be manual (set a fixed instance count) or automatic via autoscale rules. Autoscale requires Standard tier or higher.
Autoscale rules
Autoscale rules define when to add or remove instances automatically:
- Metric-based rules: trigger when a metric crosses a threshold. Common metrics: CPU percentage, memory percentage, HTTP queue length, requests per second. Each rule specifies direction (scale out / scale in), instance count change, and a cooldown period.
- Schedule-based rules: scale to a specific instance count at a defined time (e.g. scale to 5 instances weekdays at 08:00, scale to 2 at 20:00).
Authentication / Authorization (Easy Auth)
App Service has a built-in authentication and authorisation layer called Easy Auth. It integrates with identity providers — Microsoft Entra ID, Facebook, Google, Apple, Twitter — without any changes to your application code.
How Easy Auth works
Easy Auth operates as middleware that runs before requests reach your application code. Unauthenticated requests are intercepted and redirected to the configured identity provider's login page. After successful authentication, the provider returns a token, and Easy Auth injects the user's identity information into HTTP request headers (X-MS-CLIENT-PRINCIPAL, X-MS-CLIENT-PRINCIPAL-NAME) that your application can read if needed.
Configuration options
- Require authentication: any unauthenticated request is rejected (HTTP 401) or redirected to login.
- Allow unauthenticated requests: your app receives all requests but gets the identity headers when a user is authenticated. Your code handles authorisation logic.
- Token store: App Service can cache and refresh tokens, making them available to your app via
/.auth/meendpoint.
Networking: VNet Integration and Private Endpoints
App Service networking has two distinct axes that confuse many candidates: outbound (traffic leaving the app) and inbound (traffic arriving at the app). VNet Integration controls outbound; Private Endpoints control inbound.
VNet Integration
VNet Integration allows the App Service app to make outbound calls to resources in a VNet — a database on a private IP, an internal API, an on-premises service reached via ExpressRoute/VPN. The app's outbound traffic is routed through a delegated subnet in the target VNet.
myapp.azurewebsites.net) remains publicly accessible. To make inbound traffic private, you need a Private Endpoint.
Private Endpoints for App Service
A Private Endpoint assigns a private IP address (from your VNet) to the App Service app's inbound interface. Traffic from within the VNet (or connected networks) reaches the app over the private IP. The public endpoint can optionally be disabled, making the app inaccessible from the public internet.
| Feature | Controls | Minimum Tier | Effect on Public Endpoint |
|---|---|---|---|
| VNet Integration | Outbound (app → VNet) | Standard | No change — still public |
| Private Endpoint | Inbound (VNet → app) | Premium v2/v3 or Isolated | Can disable public access |
| Access Restrictions | Inbound IP allow/deny rules | Any paid tier | Filters but keeps public endpoint |
App Service Environment (ASE) v3
An App Service Environment is a fully isolated, single-tenant deployment of App Service into your own VNet. It is the most private and compliant App Service option — all inbound and outbound traffic stays within your network perimeter.
ASE deployment modes
- External ASE: inbound traffic arrives via a public VIP (load balancer with a public IP). Still network-isolated but internet-reachable through the public IP.
- Internal Load Balancer (ILB) ASE: inbound traffic only via a private VIP on the VNet. The ASE is completely unreachable from the public internet — traffic must originate from within the VNet or connected networks (ExpressRoute, VPN).
Diagnostics and Monitoring
App Service Logs
Configurable in the App Service Monitoring → App Service Logs blade:
- Application logging: output from your app's logging framework (stderr/stdout). Stored to filesystem (short-lived) or Blob Storage (long-term). Configurable verbosity level.
- Web server logging: raw HTTP request/response logs (IIS-format on Windows, nginx-format on Linux). Stored to filesystem or Blob Storage.
- Detailed error messages: HTML pages with full error details, saved to disk for 4XX and 5XX responses.
- Failed request tracing: full IIS-level request traces for requests that fail. Useful for diagnosing intermittent failures.
Log Stream
The Log Stream feature streams live application and web server log output to your browser or Azure CLI session in real time. Useful for debugging a live issue — no need to pull log files manually.
Application Insights
Application Insights is the recommended telemetry solution for App Service. It provides distributed tracing, performance monitoring, dependency tracking, exception logging, and live metrics. Integration is available as a one-click enable from the App Service portal blade (code-based instrumentation) or via the Application Insights SDK added to your application code. App Insights stores data in a Log Analytics workspace.
WebJobs
WebJobs are background tasks that run in the same App Service Plan as your main app, using the same compute allocation. They are a lightweight way to run background processing without a separate service:
- Continuous WebJobs: start immediately and run on a loop. Useful for queue processors, background polling tasks.
- Triggered WebJobs: run on a CRON schedule or on-demand. Useful for periodic batch jobs, nightly data processing.
Check Your Understanding
Click any option to see immediate feedback. Answers represent correct behaviour in a real Azure environment.
1. A developer is using a Basic (B1) App Service Plan and wants to use deployment slots for zero-downtime deployments. What must they do?
2. Your App Service has a production slot and a staging slot. The staging slot is configured with a DB_CONNECTION app setting pointing to the staging database. You want to ensure that after a slot swap, production always uses the production database connection string. What should you configure?
3. You enable VNet Integration on your Standard tier App Service app so it can reach a SQL Managed Instance on a private IP in your VNet. A security auditor asks if the App Service is now accessible only from within the VNet. What is the correct answer?
4. You set WEBSITE_RUN_FROM_PACKAGE=1 on your App Service app and deploy a ZIP file. A developer reports that the app fails when it tries to write a log file to /home/site/wwwroot/logs/. What is the cause?
/home/LogFiles/ directory (backed by shared storage), mount an Azure Files volume, or write to Azure Blob Storage directly.5. You enable Easy Auth on an App Service app and configure Microsoft Entra ID as the identity provider with "Require authentication" mode. What happens when an unauthenticated user hits the app's URL?
6. A team wants to add TLS to their app at the apex domain contoso.com (not a subdomain). They want a free certificate. Which option should they use?
Read the full overview and the linked articles on App Service Plans, deployment slots, and VNet integration. The networking section is particularly important for the exam — the inbound/outbound distinction is tested repeatedly.
This lesson covered the core App Service concepts. Explore these topics deeper in a follow-up conversation:
- Walk me through a complete zero-downtime deployment workflow using slots, including how to smoke-test staging before swapping.
- What is the difference between App Service autoscale rules and Azure Monitor autoscale — are they the same thing?
- When should I use App Service for containers vs. Azure Container Apps vs. AKS?
- How do I configure a managed identity on App Service to access Key Vault secrets without storing credentials in app settings?