Capstone: Designing and Hardening a Production IIS Deployment
IIS In Depth
Chapter 10 · Capstone: Designing and Hardening a Production IIS Deployment
Web Servers Fundamentals' own capstone compared three servers across several scenarios. This one is different, by design — the same shape Nginx In Depth's and Apache In Depth's own capstones both used: a single, cohesive worked example, layering in each of this course's own eight prior chapters, one at a time, until one complete, production-shaped IIS deployment exists.
The Scenario
One IIS server hosts one site, www.example.com, serving a customer-facing ASP.NET Core storefront application at the site root, plus a small internal reporting API reachable at /api — used only by staff on the corporate network, never by customers. Both need to keep working reliably, and the internal API specifically must never be able to take the storefront down with it if something goes wrong.
Step 1 — Application Pool Design (Chapter 2)
Two separate pools, each under its own dedicated ApplicationPoolIdentity — no shared built-in account, so a compromise or misconfiguration in one pool's identity carries no access to the other's resources. The storefront pool runs AlwaysRunning, since checkout traffic can't tolerate a cold-start latency spike. The reporting API pool keeps the default 29-hour scheduled recycle — it's genuinely low-traffic, so a brief overlapped recycle is a non-issue.
Step 2 — Locking the Configuration Model (Chapter 3)
The authentication section ships Deny-locked by default, exactly as Chapter 3 covered — so enabling Windows Authentication for /api specifically (needed in Step 7) has to happen via a <location> block in applicationHost.config, not from /api's own web.config. Every other section stays at its default overrideModeDefault, since neither application needs anything else locked down beyond this one deliberate exception.
Step 3 — Handler Mapping for ASP.NET Core (Chapter 4)
Both applications run in Integrated mode, the modern default from Chapter 4 — the storefront's own managed authentication and session modules see every request uniformly, static assets included, exactly the unified pipeline that would have been impossible under the old Classic mode's split native/ASP.NET handling.
Step 4 — Promoting /api to Its Own Application (Chapter 5)
/api is deliberately an application, not a plain virtual directory — precisely so it gets its own Application Pool and its own isolated .NET AppDomain, per Chapter 5. If the reporting API ever crash-loops into Rapid-Fail Protection, only ReportingApiPool goes offline — the storefront's own StorefrontPool is a completely separate worker process, untouched.
Step 5 — URL Rewrite for the Storefront (Chapter 6)
Applied only to the storefront, not /api — a real customer-facing Redirect to enforce HTTPS, and an internal Rewrite for clean product URLs, exactly the Rewrite-vs-Redirect distinction Chapter 6 drew. No rule here ever points at a different backend server's URL — this stays entirely within-server rewriting, deliberately not reaching for ARR.
Step 6 — HTTPS Binding with SNI (Chapter 7)
A single certificate, installed in the Windows Certificate Store and bound by thumbprint via SNI — /api shares this exact binding, since it's a path under the same site, not a separate site with its own certificate needs. A recurring calendar reminder is set for 30 days before expiry, specifically so the binding's thumbprint gets updated the moment the certificate is renewed, per Chapter 7's own renewal gotcha.
Step 7 — Authentication and Filtering for /api (Chapter 8)
/api uses Windows Authentication (enabled via Step 2's own <location> override) with an SPN explicitly registered for www.example.com against the reporting service account — done up front here specifically to avoid Chapter 8's own silent-NTLM-fallback trap. ipSecurity restricts /api to the corporate network's own subnet, deny-by-default. Request Filtering blocks .config requests site-wide, so neither application can ever accidentally expose its own web.config contents.
Step 8 — Performance, Logging & a Pre-Flight Tracing Check (Chapter 9)
Static assets (.css, images) get kernel-mode caching — genuinely eligible, since they're anonymous and untouched by URL Rewrite. The storefront's own product pages stay out of kernel-mode caching deliberately, since Step 5's own Rewrite rule applies to them, exactly the eligibility gotcha Chapter 9 named. Failed Request Tracing is scoped tightly to /api alone and only to genuine failure status codes — enabled for the initial rollout window to verify the new Windows Authentication and IP restriction rules actually behave as intended, with a plan to disable it once that's confirmed rather than leaving it running indefinitely.
| Capstone Step | Chapter It Draws From |
|---|---|
| Step 1 — Application Pool identities & recycling | Chapter 2 |
| Step 2 — Locking authentication via <location> | Chapter 3 |
| Step 3 — Handler mapping & Integrated mode | Chapter 4 |
| Step 4 — /api as its own isolated application | Chapter 5 |
| Step 5 — URL Rewrite (HTTPS enforcement, friendly URLs) | Chapter 6 |
| Step 6 — HTTPS binding with SNI | Chapter 7 |
| Step 7 — Windows Authentication, SPN, IP restriction, filtering | Chapter 8 |
| Step 8 — Compression, caching, scoped Failed Request Tracing | Chapter 9 |
Hands-On Exercises
Explain why /api was deliberately made its own application in Step 4 rather than left as a plain subfolder under the storefront's own application, referencing both Chapter 2 and Chapter 5's own material.
📄 View solutionA colleague suggests also adding the storefront's own /product.aspx pages to the kernel-mode caching profile used for .css files in Step 8, to speed things up further. Explain why this wouldn't actually work as intended, using this chapter's own Step 5 and Step 8 together.
📄 View solutionWrite a short chapter-attribution summary (2-3 sentences) explaining how this capstone's own shape differs from Web Servers Fundamentals' own capstone, and why that difference makes sense given what each course actually covers.
📄 View solutionIIS In Depth — 10 of 10 chapters complete. The Web Servers subject now has its comparative foundation, its Nginx deep dive, its Apache deep dive, and its IIS deep dive.
Chapter 10 Quick Reference
- This capstone builds one cohesive production deployment for a public storefront and an isolated internal API under the same site, layering in Chapters 2 through 9 step by step — the same deliberate shape as Nginx In Depth's and Apache In Depth's own capstones, and a different one from Web Servers Fundamentals' own multi-scenario decision framework
- Promoting
/apito its own application (Chapter 5) with its own Application Pool (Chapter 2) is what keeps a reporting-API crash from ever taking the storefront down with it - Kernel-mode caching only applies to content untouched by URL Rewrite or non-anonymous authentication (Chapter 9) — deliberately excluded here for the storefront's own rewritten product pages
- Registering the SPN and restricting Windows Authentication and IP access to
/apiup front avoids both of Chapter 8's own named gotchas — silent NTLM fallback and an open internal endpoint - A working deployment is a foundation, not a complete production rollout — staged traffic cutover, real alerting, and a documented certificate-renewal process still matter beyond this chapter's own scope