.net core
205 TopicsAgentic IIS Migration to Managed Instance on Azure App Service
Introduction Enterprises running ASP.NET Framework workloads on Windows Server with IIS face a familiar dilemma: modernize or stay put. The applications work, the infrastructure is stable, and nobody wants to be the person who breaks production during a cloud migration. But the cost of maintaining aging on-premises servers, patching Windows, and managing IIS keeps climbing. Azure App Service has long been the lift-and-shift destination for these workloads. But what about applications that depend on Windows registry keys, COM components, SMTP relay, MSMQ queues, local file system access, or custom fonts? These OS-level dependencies have historically been migration blockers — forcing teams into expensive re-architecture or keeping them anchored to VMs. Managed Instance on Azure App Service changes this equation entirely. And the IIS Migration MCP Server makes migration guided, intelligent, and safe — with AI agents that know what to ask, what to check, and what to generate at every step. What Is Managed Instance on Azure App Service? Managed Instance on App Service is Azure's answer to applications that need OS-level customization beyond what standard App Service provides. It runs on the PremiumV4 (PV4) SKU with IsCustomMode=true, giving your app access to: Capability What It Enables Registry Adapters Redirect Windows Registry reads to Azure Key Vault secrets — no code changes Storage Adapters Mount Azure Files, local SSD, or private VNET storage as drive letters (e.g., D:\, E:\) install.ps1 Startup Script Run PowerShell at instance startup to install Windows features (SMTP, MSMQ), register COM components, install MSI packages, deploy custom fonts Custom Mode Full access to the Windows instance for configuration beyond standard PaaS guardrails The key constraint: Managed Instance on App Service requires PV4 SKU with IsCustomMode=true. No other SKU combination supports it. Why Managed Instance Matters for Legacy Apps Consider a classic enterprise ASP.NET application that: Reads license keys from HKLM\SOFTWARE\MyApp in the Windows Registry Uses a COM component for PDF generation registered via regsvr32 Sends email through a local SMTP relay Writes reports to D:\Reports\ on a local drive Uses a custom corporate font for PDF rendering With standard App Service, you'd need to rewrite every one of these dependencies. With Managed Instance on App Service, you can: Map registry reads to Key Vault secrets via Registry Adapters Mount Azure Files as D:\ via Storage Adapters Enable SMTP Server via install.ps1 Register the COM DLL via install.ps1 (regsvr32) Install the custom font via install.ps1 Please note that when you are migrating your web applications to Managed Instance on Azure App Service in majority of the use cases "Zero application code changes may be required " but depending on your specific web app some code changes may be necessary. Microsoft Learn Resources Managed Instance on App Service Overview Azure App Service Documentation App Service Migration Assistant Tool Migrate to Azure App Service Azure App Service Plans Overview PremiumV4 Pricing Tier Azure Key Vault Azure Files AppCat (.NET) — Azure Migrate Application and Code Assessment Why Agentic Migration? The Case for AI-Guided IIS Migration The Problem with Traditional Migration Microsoft provides excellent PowerShell scripts for IIS migration — Get-SiteReadiness.ps1, Get-SitePackage.ps1, Generate-MigrationSettings.ps1, and Invoke-SiteMigration.ps1. They're free, well-tested, and reliable. So why wrap them in an AI-powered system? Because the scripts are powerful but not intelligent. They execute what you tell them to. They don't tell you what to do. Here's what a traditional migration looks like: Run readiness checks — get a wall of JSON with cryptic check IDs like ContentSizeCheck, ConfigErrorCheck, GACCheck Manually interpret 15+ readiness checks per site across dozens of sites Decide whether each site needs Managed Instance or standard App Service (how?) Figure out which dependencies need registry adapters vs. storage adapters vs. install.ps1 (the "Managed Instance provisioning split") Write the install.ps1 script by hand for each combination of OS features Author ARM templates for adapter configurations (Key Vault references, storage mount specs, RBAC assignments) Wire together PackageResults.json → MigrationSettings.json with correct Managed Instance fields (Tier=PremiumV4, IsCustomMode=true) Hope you didn't misconfigure anything before deploying to Azure Even experienced Azure engineers find this time-consuming, error-prone, and tedious — especially across a fleet of 20, 50, or 100+ IIS sites. What Agentic Migration Changes The IIS Migration MCP Server introduces an AI orchestration layer that transforms this manual grind into a guided conversation: Traditional Approach Agentic Approach Read raw JSON output from scripts AI summarizes readiness as tables with plain-English descriptions Memorize 15 check types and their severity AI enriches each check with title, description, recommendation, and documentation links Manually decide Managed Instance vs App Service recommend_target analyzes all signals and recommends with confidence + reasoning Write install.ps1 from scratch generate_install_script builds it from detected features Author ARM templates manually generate_adapter_arm_template generates full templates with RBAC guidance Wire JSON artifacts between phases by hand Agents pass readiness_results_path → package_results_path → migration_settings_path automatically Pray you set PV4 + IsCustomMode correctly Enforced automatically — every tool validates Managed Instance constraints Deploy and find out what broke confirm_migration presents a full cost/resource summary before touching Azure The core value proposition: the AI knows the Managed Instance provisioning split. It knows that registry access needs an ARM template with Key Vault-backed adapters, while SMTP needs an install.ps1 section enabling the Windows SMTP Server feature. You don't need to know this. The system detects it from your IIS configuration and AppCat analysis, then generates exactly the right artifacts. Human-in-the-Loop Safety Agentic doesn't mean autonomous. The system has explicit gates: Phase 1 → Phase 2: "Do you want to assess these sites, or skip to packaging?" Phase 3: "Here's my recommendation — Managed Instance for Site A (COM + Registry), standard for Site B. Agree?" Phase 4: "Review MigrationSettings.json before proceeding" Phase 5: "This will create billable Azure resources. Type 'yes' to confirm" The AI accelerates the workflow; the human retains control over every decision. Quick Start Clone and set up the MCP server git clone https://github.com//iis-migration-mcp.git cd iis-migration-mcp python -m venv .venv .venv\Scripts\activate pip install -r requirements.txt # Download Microsoft's migration scripts (NOT included in this repo) # From: https://appmigration.microsoft.com/api/download/psscripts/AppServiceMigrationScripts.zip # Unzip to C:\MigrationScripts (or your preferred path) # Start using in VS Code with Copilot # 1. Copy .vscode/mcp.json.example → .vscode/mcp.json # 2. Open folder in VS Code # 3. In Copilot Chat: "Configure scripts path to C:\MigrationScripts" # 4. Then: @iis-migrate "Discover my IIS sites" The server also works with any MCP-compatible client — Claude Desktop, Cursor, Copilot CLI, or custom integrations — via stdio transport. Architecture: How the MCP Server Works The system is built on the Model Context Protocol (MCP), an open protocol that lets AI assistants like GitHub Copilot, Claude, or Cursor call external tools through a standardized interface. ┌──────────────────────────────────────────────────────────────────┐ │ VS Code + Copilot Chat │ │ @iis-migrate orchestrator agent │ │ ├── iis-discover (Phase 1) │ │ ├── iis-assess (Phase 2) │ │ ├── iis-recommend (Phase 3) │ │ ├── iis-deploy-plan (Phase 4) │ │ └── iis-execute (Phase 5) │ └─────────────┬────────────────────────────────────────────────────┘ │ stdio JSON-RPC (MCP Transport) ▼ ┌──────────────────────────────────────────────────────────────────┐ │ FastMCP Server (server.py) │ │ 13 Python Tool Modules (tools/*.py) │ │ └── ps_runner.py (Python → PowerShell bridge) │ │ └── Downloaded PowerShell Scripts (user-configured) │ │ ├── Local IIS (discovery, packaging) │ │ └── Azure ARM API (deployment) │ └──────────────────────────────────────────────────────────────────┘ The server exposes 13 MCP tools organized across 5 phases, orchestrated by 6 Copilot agents (1 orchestrator + 5 specialist subagents). Important: The PowerShell migration scripts are not included in this repository. Users must download them from GitHub and configure the path using the configure_scripts_path tool. This ensures you always use the latest version of Microsoft's scripts, avoiding version mismatch issues. The 13 MCP Tools: Complete Reference Phase 0 — Setup configure_scripts_path Purpose: Point the server to Microsoft's downloaded migration PowerShell scripts. Before any migration work, you need to download the scripts from GitHub, unzip them, and tell the server where they are. "Configure scripts path to C:\MigrationScripts" Phase 1 — Discovery 1. discover_iis_sites Purpose: Scan the local IIS server and run readiness checks on every web site. This is the entry point for every migration. It calls Get-SiteReadiness.ps1 under the hood, which: Enumerates all IIS web sites, application pools, bindings, and virtual directories Runs 15 readiness checks per site (config errors, HTTPS bindings, non-HTTP protocols, TCP ports, location tags, app pool settings, app pool identity, virtual directories, content size, global modules, ISAPI filters, authentication, framework version, connection strings, and more) Detects source code artifacts (.sln, .csproj, .cs, .vb) near site physical paths Output: ReadinessResults.json with per-site status: Status Meaning READY No issues detected — clear for migration READY_WITH_WARNINGS Minor issues that won't block migration READY_WITH_ISSUES Non-fatal issues that need attention BLOCKED Fatal issues (e.g., content > 2GB) — cannot migrate as-is Requires: Administrator privileges, IIS installed. 2. choose_assessment_mode Purpose: Route each discovered site into the appropriate next step. After discovery, you decide the path for each site: assess_all: Run detailed assessment on all non-blocked sites package_and_migrate: Skip assessment, proceed directly to packaging (for sites you already know well) The tool classifies each site into one of five actions: assess_config_only — IIS/web.config analysis assess_config_and_source — Config + AppCat source code analysis (when source is detected) package — Skip to packaging blocked — Fatal errors, cannot proceed skip — User chose to exclude Phase 2 — Assessment 3. assess_site_readiness Purpose: Get a detailed, human-readable readiness assessment for a specific site. Takes the raw readiness data from Phase 1 and enriches each check with: Title: Plain-English name (e.g., "Global Assembly Cache (GAC) Dependencies") Description: What the check found and why it matters Recommendation: Specific guidance on how to resolve the issue Category: Grouping (Configuration, Security, Compatibility) Documentation Link: Microsoft Learn URL for further reading This enrichment comes from WebAppCheckResources.resx, an XML resource file that maps check IDs to detailed metadata. Without this tool, you'd see GACCheck: FAIL — with it, you see the full context. Output: Overall status, enriched failed/warning checks, framework version, pipeline mode, binding details. 4. assess_source_code Purpose: Analyze an Azure Migrate application and code assessment for .NET JSON report to identify Managed Instance-relevant source code dependencies. If your application has source code and you've run the assessment tool against it, this tool parses the results and maps findings to migration actions: Dependency Detected Migration Action Windows Registry access Registry Adapter (ARM template) Local file system I/O / hardcoded paths Storage Adapter (ARM template) SMTP usage install.ps1 (SMTP Server feature) COM Interop install.ps1 (regsvr32/RegAsm) Global Assembly Cache (GAC) install.ps1 (GAC install) Message Queuing (MSMQ) install.ps1 (MSMQ feature) Certificate access Key Vault integration The tool matches rules from the assessment output against known Managed Instance-relevant patterns. For a complete list of rules and categories, see Interpret the analysis results. Output: Issues categorized as mandatory/optional/potential, plus install_script_features and adapter_features lists that feed directly into Phase 3 tools. Phase 3 — Recommendation & Provisioning 5. suggest_migration_approach Purpose: Recommend the right migration tool/approach for the scenario. This is a routing tool that considers: Source code available? → Recommend the App Modernization MCP server for code-level changes No source code? → Recommend this IIS Migration MCP (lift-and-shift) OS customization needed? → Highlight Managed Instance on App Service as the target 6. recommend_target Purpose: Recommend the Azure deployment target for each site based on all assessment data. This is the intelligence center of the system. It analyzes config assessments and source code findings to recommend: Target When Recommended SKU MI_AppService Registry, COM, MSMQ, SMTP, local file I/O, GAC, or Windows Service dependencies detected PremiumV4 (PV4) AppService Standard web app, no OS-level dependencies PremiumV2 (PV2) ContainerApps Microservices architecture or container-first preference N/A Each recommendation comes with: Confidence: high or medium Reasoning: Full explanation of why this target was chosen Managed Instance reasons: Specific dependencies that require Managed Instance Blockers: Issues that prevent migration entirely install_script_features: What the install.ps1 needs to enable adapter_features: What the ARM template needs to configure Provisioning guidance: Step-by-step instructions for what to do next 7. generate_install_script Purpose: Generate an install.ps1 PowerShell script for OS-level feature enablement on Managed Instance. This handles the OS-level side of the Managed Instance provisioning split. It generates a startup script that includes sections for: Feature What the Script Does SMTP Install-WindowsFeature SMTP-Server, configure smart host relay MSMQ Install MSMQ, create application queues COM/MSI Run msiexec for MSI installers, regsvr32/RegAsm for COM registration Crystal Reports Install SAP Crystal Reports runtime MSI Custom Fonts Copy .ttf/.otf to C:\Windows\Fonts, register in registry The script can auto-detect needed features from config and source assessments, or you can specify them manually. 8. generate_adapter_arm_template Purpose: Generate an ARM template for Managed Instance registry and storage adapters. This handles the platform-level side of the Managed Instance provisioning split. It generates a deployable ARM template that configures: Registry Adapters (Key Vault-backed): Map Windows Registry paths (e.g., HKLM\SOFTWARE\MyApp\LicenseKey) to Key Vault secrets Your application reads the registry as before; Managed Instance redirects the read to Key Vault transparently Storage Adapters (three types): Type Description Credentials AzureFiles Mount Azure Files SMB share as a drive letter Storage account key in Key Vault Custom Mount storage over private endpoint via VNET Requires VNET integration LocalStorage Allocate local SSD on the Managed Instance as a drive letter None needed The template also includes: Managed Identity configuration RBAC role assignments guidance (Key Vault Secrets User, Storage File Data SMB Share Contributor, etc.) Deployment CLI commands ready to copy-paste Phase 4 — Deployment Planning & Packaging 9. plan_deployment Purpose: Plan the Azure App Service deployment — plans, SKUs, site assignments. Collects your Azure details (subscription, resource group, region) and creates a validated deployment plan: Assigns sites to App Service Plans Enforces PV4 + IsCustomMode=true for Managed Instance — won't let you accidentally use the wrong SKU Supports single_plan (all sites on one plan) or multi_plan (separate plans) Optionally queries Azure for existing Managed Instance plans you can reuse 10. package_site Purpose: Package IIS site content into ZIP files for deployment. Calls Get-SitePackage.ps1 to: Compress site binaries + web.config into deployment-ready ZIPs Optionally inject install.ps1 into the package (so it deploys alongside the app) Handle sites with non-fatal issues (configurable) Size limit: 2 GB per site (enforced by System.IO.Compression). 11. generate_migration_settings Purpose: Create the MigrationSettings.json deployment configuration. This is the final configuration artifact. It calls Generate-MigrationSettings.ps1 and then post-processes the output to inject Managed Instance-specific fields: Important: The Managed Instance on App Service Plan is not automatically created by the migration tools. You must pre-create the Managed Instance on App Service Plan (PV4 SKU with IsCustomMode=true) in the Azure portal or via CLI before generating migration settings. When running generate_migration_settings, provide the name of your existing Managed Instance plan so the settings file references it correctly. { "AppServicePlan": "mi-plan-eastus", "Tier": "PremiumV4", "IsCustomMode": true, "InstallScriptPath": "install.ps1", "Region": "eastus", "Sites": [ { "IISSiteName": "MyLegacyApp", "AzureSiteName": "mylegacyapp-azure", "SitePackagePath": "packagedsites/MyLegacyApp_Content.zip" } ] } Phase 5 — Execution 12. confirm_migration Purpose: Present a full migration summary and require explicit human confirmation. Before touching Azure, this tool displays: Total plans and sites to be created SKU and pricing tier per plan Whether Managed Instance is configured Cost warning for PV4 pricing Resource group, region, and subscription details Nothing proceeds until the user explicitly confirms. 13. migrate_sites Purpose: Deploy everything to Azure App Service. This creates billable resources. Calls Invoke-SiteMigration.ps1, which: Sets Azure subscription context Creates/validates resource groups Creates App Service Plans (PV4 with IsCustomMode for Managed Instance) Creates Web Apps Configures .NET version, 32-bit mode, pipeline mode from the original IIS settings Sets up virtual directories and applications Disables basic authentication (FTP + SCM) for security Deploys ZIP packages via Azure REST API Output: MigrationResults.json with per-site Azure URLs, Resource IDs, and deployment status. The 6 Copilot Agents The MCP tools are orchestrated by a team of specialized Copilot agents — each responsible for a specific phase of the migration lifecycle. @iis-migrate — The Orchestrator The root agent that guides the entire migration. It: Tracks progress across all 5 phases using a todo list Delegates work to specialist subagents Gates between phases — asks before transitioning Enforces the Managed Instance constraint (PV4 + IsCustomMode) at every decision point Never skips the Phase 5 confirmation gate Usage: Open Copilot Chat and type @iis-migrate I want to migrate my IIS applications to Azure iis-discover — Discovery Specialist Handles Phase 1. Runs discover_iis_sites, presents a summary table of all sites with their readiness status, and asks whether to assess or skip to packaging. Returns readiness_results_path and per-site routing plans. iis-assess — Assessment Specialist Handles Phase 2. Runs assess_site_readiness for every site, and assess_source_code when AppCat results are available. Merges findings, highlights Managed Instance-relevant issues, and produces the adapter/install features lists that drive Phase 3. iis-recommend — Recommendation Specialist Handles Phase 3. Runs recommend_target for each site, then conditionally generates install.ps1 and ARM adapter templates. Presents all recommendations with confidence levels and reasoning, and allows you to edit generated artifacts. iis-deploy-plan — Deployment Planning Specialist Handles Phase 4. Collects Azure details, runs plan_deployment, package_site, and generate_migration_settings. Validates Managed Instance configuration, allows review and editing of MigrationSettings.json. Does not execute migration. iis-execute — Execution Specialist Handles Phase 5 only. Runs confirm_migration to present the final summary, then only proceeds with migrate_sites after receiving explicit "yes" confirmation. Reports results with Azure URLs and deployment status. The Managed Instance Provisioning Split: A Critical Concept One of the most important ideas Managed Instance introduces is the provisioning split — the division of OS dependencies into two categories that are configured through different mechanisms: ┌──────────────────────────────────────────────────────────────┐ │ MANAGED INSTANCE PROVISIONING SPLIT │ ├─────────────────────────────┬────────────────────────────────┤ │ ARM Template │ install.ps1 │ │ (Platform-Level) │ (OS-Level) │ ├─────────────────────────────┼────────────────────────────────┤ │ Registry Adapters │ COM/MSI Registration │ │ → Key Vault secrets │ → regsvr32, RegAsm, msiexec │ │ │ │ │ Storage Mounts │ SMTP Server Feature │ │ → Azure Files │ → Install-WindowsFeature │ │ → Local SSD │ │ │ → VNET private storage │ MSMQ │ │ │ → Message queue setup │ │ │ │ │ │ Crystal Reports Runtime │ │ │ → SAP MSI installer │ │ │ │ │ │ Custom Fonts │ │ │ → Copy to C:\Windows\Fonts │ └─────────────────────────────┴────────────────────────────────┘ The MCP server handles this split automatically: assess_source_code detects which dependencies fall into which category recommend_target reports both adapter_features and install_script_features generate_adapter_arm_template builds the ARM template for platform features generate_install_script builds the PowerShell startup script for OS features You don't need to remember which goes where — the system decides and generates the right artifacts. End-to-End Walkthrough: From Discovery to Running on Managed Instance Here's what a complete migration conversation looks like: You: "@iis-migrate I want to migrate my IIS applications to Azure" Phase 1 — Discovery: Agent runs discover_iis_sites, presents a table: Site Status Framework Source Code? HRPortal READY_WITH_ISSUES v4.8 Yes (.sln found) PayrollAPI READY v4.8 No IntranetCMS BLOCKED (>2GB) v4.7.2 No Phase 2 — Assessment: Agent runs assess_site_readiness for HRPortal — finds GACCheck and RegistryCheck failures. Runs assess_source_code using AppCat report — confirms COM interop, registry access, and SMTP usage. Phase 3 — Recommendation: Agent runs recommend_target: HRPortal → MI_AppService (high confidence) — COM, registry, SMTP dependencies PayrollAPI → AppService (high confidence) — no OS dependencies Generates install.ps1 for HRPortal (SMTP + COM sections). Generates ARM template with registry adapter (Key Vault-backed) for HRPortal. Phase 4 — Deployment Planning: Agent collects subscription/RG/region, validates PV4 availability. Packages both sites. Generates MigrationSettings.json with two plans: mi-plan-hrportal (PremiumV4, IsCustomMode=true) — HRPortal std-plan-payrollapi (PremiumV2) — PayrollAPI Phase 5 — Execution: Agent shows full summary with cost projection. You type "yes". Sites deploy. You get Azure URLs within minutes. Prerequisites & Setup Requirement Purpose Windows Server with IIS Source server for discovery and packaging PowerShell 5.1 Runs migration scripts (ships with Windows) Python 3.10+ MCP server runtime Administrator privileges Required for IIS discovery, packaging, and migration Azure subscription Target for deployment (execution phase only) Azure PowerShell (Az module) Deploy to Azure (execution phase only) Migration Scripts ZIP Microsoft's PowerShell migration scripts AppCat CLI Source code analysis (optional) FastMCP (mcp[cli]>=1.0.0) MCP server framework Data Flow & Artifacts Every phase produces JSON artifacts that chain into the next phase: Phase 1: discover_iis_sites ──→ ReadinessResults.json │ Phase 2: assess_site_readiness ◄──────┘ assess_source_code ───→ Assessment JSONs │ Phase 3: recommend_target ◄───────────┘ generate_install_script ──→ install.ps1 generate_adapter_arm ─────→ mi-adapters-template.json │ Phase 4: package_site ────────────→ PackageResults.json + site ZIPs generate_migration_settings → MigrationSettings.json │ Phase 5: confirm_migration ◄──────────┘ migrate_sites ───────────→ MigrationResults.json │ ▼ Apps live on Azure *.azurewebsites.net Each artifact is inspectable, editable, and auditable — providing a complete record of what was assessed, recommended, and deployed. Error Handling The MCP server classifies errors into actionable categories: Error Cause Resolution ELEVATION_REQUIRED Not running as Administrator Restart VS Code / terminal as Admin IIS_NOT_FOUND IIS or WebAdministration module missing Install IIS role + WebAdministration AZURE_NOT_AUTHENTICATED Not logged into Azure PowerShell Run Connect-AzAccount SCRIPT_NOT_FOUND Migration scripts path not configured Run configure_scripts_path SCRIPT_TIMEOUT PowerShell script exceeded time limit Check IIS server responsiveness OUTPUT_NOT_FOUND Expected JSON output wasn't created Verify script execution succeeded Conclusion The IIS Migration MCP Server turns what used to be a multi-week, expert-driven project into a guided conversation. It combines Microsoft's battle-tested migration PowerShell scripts with AI orchestration that understands the nuances of Managed Instance on App Service — the provisioning split, the PV4 constraint, the adapter configurations, and the OS-level customizations. Whether you're migrating 1 site or 10, agentic migration reduces risk, eliminates guesswork, and produces auditable artifacts at every step. The human stays in control; the AI handles the complexity. Get started: Download the migration scripts, set up the MCP server, and ask @iis-migrate to discover your IIS sites. The agents will take it from there. This project is compatible with any MCP-enabled client: VS Code GitHub Copilot, Claude Desktop, Cursor, and more. The intelligence travels with the server, not the client.203Views0likes0CommentsContinued Investment in Azure App Service
This blog was originally published to the App Service team blog Recent Investments Premium v4 (Pv4) Azure App Service Premium v4 delivers higher performance and scalability on newer Azure infrastructure while preserving the fully managed PaaS experience developers rely on. Premium v4 offers expanded CPU and memory options, improved price-performance, and continued support for App Service capabilities such as deployment slots, integrated monitoring, and availability zone resiliency. These improvements help teams modernize and scale demanding workloads without taking on additional operational complexity. App Service Managed Instance App Service Managed Instance extends the App Service model to support Windows web applications that require deeper environment control. It enables plan-level isolation, optional private networking, and operating system customization while retaining managed scaling, patching, identity, and diagnostics. Managed Instance is designed to reduce migration friction for existing applications, allowing teams to move to a modern PaaS environment without code changes. Faster Runtime and Language Support Azure App Service continues to invest in keeping pace with modern application stacks. Regular updates across .NET, Node.js, Python, Java, and PHP help developers adopt new language versions and runtime improvements without managing underlying infrastructure. Reliability and Availability Improvements Ongoing investments in platform reliability and resiliency strengthen production confidence. Expanded Availability Zone support and related infrastructure improvements help applications achieve higher availability with more flexible configuration options as workloads scale. Deployment Workflow Enhancements Deployment workflows across Azure App Service continue to evolve, with ongoing improvements to GitHub Actions, Azure DevOps, and platform tooling. These enhancements reduce friction from build to production while preserving the managed App Service experience. A Platform That Grows With You These recent investments reflect a consistent direction for Azure App Service: active development focused on performance, reliability, and developer productivity. Improvements to runtimes, infrastructure, availability, and deployment workflows are designed to work together, so applications benefit from platform progress without needing to re-architect or change operating models. The recent General Availability of Aspire on Azure App Service is another example of this direction. Developers building distributed .NET applications can now use the Aspire AppHost model to define, orchestrate, and deploy their services directly to App Service — bringing a code-first development experience to a fully managed platform. We are also seeing many customers build and run AI-powered applications on Azure App Service, integrating models, agents, and intelligent features directly into their web apps and APIs. App Service continues to evolve to support these scenarios, providing a managed, scalable foundation that works seamlessly with Azure's broader AI services and tooling. Whether you are modernizing with Premium v4, migrating existing workloads using App Service Managed Instance, or running production applications at scale - including AI-enabled workloads - Azure App Service provides a predictable and transparent foundation that evolves alongside your applications. Azure App Service continues to focus on long-term value through sustained investment in a managed platform developers can rely on as requirements grow, change, and increasingly incorporate AI. Get Started Ready to build on Azure App Service? Here are some resources to help you get started: Create your first web app — Deploy a web app in minutes using the Azure portal, CLI, or VS Code. App Service documentation — Explore guides, tutorials, and reference for the full platform. Aspire on Azure App Service — Now generally available. Deploy distributed .NET applications to App Service using the Aspire AppHost model. Pricing and plans — Compare tiers including Premium v4 and find the right fit for your workload. App Service on Azure Architecture Center — Reference architectures and best practices for production deployments.271Views1like0CommentsCode Optimizations for Azure App Service Now Available in VS Code
Today we shipped a feature in the Azure App Service extension for VS Code that answers both questions: Code Optimizations, powered by Application Insights profiler data and GitHub Copilot. The problem: production performance is a black box You've deployed your .NET app to Azure App Service. Monitoring shows CPU is elevated, and response times are creeping up. You know something is slow, but reproducing production load patterns locally is nearly impossible. Application Insights can detect these issues, but context-switching between the Azure Portal and your editor to actually fix them adds friction. What if the issues came to you, right where you write code? What's new The Azure App Service extension now adds a Code Optimizations node directly under your .NET web apps in the Azure Resources tree view. This node surfaces performance issues detected by the Application Insights profiler - things like excessive CPU or memory usage caused by specific functions in your code. Each optimization tells you: Which function is the bottleneck Which parent function is calling it What category of resource usage is affected (CPU, memory, etc.) The impact as a percentage, so you can prioritize what matters But we didn't stop at surfacing the data. Click Fix with Copilot on any optimization and the extension will: Locate the problematic code in your workspace by matching function signatures from the profiler stack trace against your local source using VS Code's workspace symbol provider Open the file and highlight the exact method containing the bottleneck Launch a Copilot Chat session pre-filled with a detailed prompt that includes the issue description, the recommendation from Application Insights, the full stack trace context, and the source code of the affected method By including the stack trace, recommendation, impact data, and the actual source code, the prompt gives Copilot enough signal to produce a meaningful, targeted fix rather than generic advice. For example, the profiler might surface a LINQ-heavy data transformation consuming 38% of CPU in OrderService.CalculateTotals, called from CheckoutController.Submit. It then prompts copilot with the problem and it them offers a fix. Prerequisites A .NET web app deployed to Azure App Service Application Insights connected to your app The Application Insights profiler enabled (the extension will prompt you if it's not) For Windows App Service plans When creating a new web app through the extension, you'll now see an option to enable the Application Insights profiler. For existing apps, the Code Optimizations node will guide you through enabling profiling if it's not already active. For Linux App Service plans Profiling on Linux requires a code-level integration rather than a platform toggle. If no issues are found, the extension provides a prompt to help you add profiler support to your application code. What's next This is the first step toward bringing production intelligence directly into the inner development loop. We're exploring how to expand this pattern beyond .NET and beyond performance — surfacing reliability issues, exceptions, and other operational insights where developers can act on them immediately. Install the latest Azure App Service extension and expand the Code Optimizations node under any .NET web app to try it out. We'd love your feedback - file issues on the GitHub repo. Happy Coding <3342Views0likes1CommentWhat AI Agents for Modernization Look Like in Practice
We’ve all been put onto an initiative to “modernize” our company’s applications. But talk about a haphazard and confusing project to be put on. Apps are older than anyone first thought, there are dependencies nobody can explain, and business critical services blocked behind another team's roadmap. Yet all of them are competing for the same developers. It’s overwhelming! What can you do? AI agents are helping teams unravel the modernization maze. Mandy Whaley wrote a recent post introducing some of the latest tech let’s take a bit of a deeper look. Most teams do not have a one-app problem GitHub Copilot modernization helps solve the problem of having to sort through several applications to modernize. You don’t have to be alone managing different complexities, dependencies, urgency, and ages of modernizing multiple applications! GitHub Copilot modernization helps create a repeatable way to understand each application before developers get their hands dirty. The GitHub Copilot modernization workflow GitHub Copilot modernization helps teams upgrade .NET projects and migrate them to Azure. It’s first going to assess your project and produce a markdown file that gives you an overview of what all needs to be done. Then it plans out the steps of the upgrade in more detail. Finally, it gets to it ,performing the code changes, fixes and validation. It works across Visual Studio, Visual Studio Code, the GitHub Copilot CLI, and GitHub.com. The Assessment Step The workflow starts with assessment: project, structure, dependencies, code patterns. GitHub Copilot modernization examines your project structure, dependencies, and code patterns to identify what needs to change. It generates an dotnet-upgrade-plan.md file in .github/upgrades so you have something concrete to review before the workflow moves forward. Plus, you can choose your .NET version (8, 9 or 10), supporting modernization standards and patterns in your organization, The Planning Step Once you approve the assessment that the GitHub Copilot modernization agent creates and you always get to approve before it proceeds to the next step,it moves on to planning. The planning step documents the approach in more detail. According to the documentation, the plan covers upgrade strategies, refactoring approaches, dependency upgrade paths, and risk mitigations. You can review and edit that Markdown before moving on to execution. The Execution Step Approve the planning document and the agent moves into execution mode. Here it breaks the plan down into discrete tasks with concrete validation criteria. And once everything looks good it begins to make changes to the code base. From there, we begin the upgrade work. If Copilot runs into a problem, it tries to identify the cause and apply a fix. Updating the task status and it creates Git commits for each portion of the process so you can review what changed or roll back if needed! The benefits of the steps By breaking each stage down into concrete steps teams get the chance to review the plan, understand what is changing, and decide where manual intervention is still needed. Architects and app owners have something concrete to look at, change if necessary, and push to version. Migrating to the cloud GitHub Copilot modernization is not limited to moving a project to a newer version of .NET. It also helps assess cloud readiness, recommend Azure resources, apply migration best practices, and support deployment to Azure. The Azure migration process of Copilot modernization helps answer questions like: Where should the application run? What services should I use with it? What parts of the application should stay in place for now, and what parts should be adapted for Azure? Teams can work through migration paths related to managed identity, Azure SQL, Azure Blob Storage, Azure File Storage, Microsoft Entra ID, Azure Key Vault, Azure Service Bus, Azure Cache for Redis, and OpenTelemetry on Azure. That is the kind of work that moves an application beyond a version update and into a more complete modernization effort. Humans still matter Agents can reduce manual work, can help teams move through assessment, planning, and repetitive tasks faster. Giving developers a better starting point and help keep progress visible in the repo. But the important decisions still belong to people! Architects still need to make tradeoffs. Application owners still need to think about business value, timing, and risk. Developers still need to review the code, check the plan, and decide where human judgment is required. The GitHub Copilot modernization speeds the process up by doing tedious work for you. You’re still in control of the decisions and responsible for the code it outputs, but it takes care of the work to perform the assessment, planning, and code changes. Give it a shot by picking just one project and running the assessment and reviewing the plan. See what it comes up with. Then when you’re ready, move on to the rest of your application portfolio. Modernization at scale still happens application by application, repo by repo, and decision by decision. Use the GitHub Copilot modernization agent, spin it up and try it, and let us know what you think in the comments.641Views0likes0CommentsFrom "Maybe Next Quarter" to "Running Before Lunch" on Container Apps - Modernizing Legacy .NET App
In early 2025, we wanted to modernize Jon Galloway's MVC Music Store — a classic ASP.NET MVC 5 app running on .NET Framework 4.8 with Entity Framework 6. The goal was straightforward: address vulnerabilities, enable managed identity, and deploy to Azure Container Apps and Azure SQL. No more plaintext connection strings. No more passwords in config files. We hit a wall immediately. Entity Framework on .NET Framework did not support Azure.Identity or DefaultAzureCredential. We just could not add a NuGet package and call it done — we’d need EF Core, which means modern .NET - and rewriting the data layer, the identity system, the startup pipeline, the views. The engineering team estimated one week of dedicated developer work. As a product manager without extensive .NET modernization experience, I wasn't able to complete it quickly on my own, so the project was placed in the backlog. This was before the GitHub Copilot "Agent" mode, the GitHub Copilot app modernization (a specialized agent with skills for modernization) existed but only offered assessment — it could tell you what needed to change, but couldn't make the end to end changes for you. Fast-forward one year. The full modernization agent is available. I sat down with the same app and the same goal. A few hours later, it was running on .NET 10 on Azure Container Apps with managed identity, Key Vault integration, and zero plaintext credentials. Thank you GitHub Copilot app modernization! And while we were on it – GitHub Copilot helped to modernize the experience as well, built more tests and generated more synthetic data for testing. Why Azure Container Apps? Azure Container Apps is an ideal deployment target for this modernized MVC Music Store application because it provides a serverless, fully managed container hosting environment. It abstracts away infrastructure management while natively supporting the key security and operational features this project required. It pairs naturally with infrastructure-as-code deployments, and its per-second billing on a consumption plan keeps costs minimal for a lightweight web app like this, eliminating the overhead of managing Kubernetes clusters while still giving you the container portability that modern .NET apps benefit from. That is why I asked Copilot to modernize to Azure Container Apps - here's how it went - Phase 1: Assessment GitHub Copilot App Modernization started by analyzing the codebase and producing a detailed assessment: Framework gap analysis — .NET Framework 4.0 → .NET 10, identifying every breaking change Dependency inventory — Entity Framework 6 (not EF Core), MVC 5 references, System.Web dependencies Security findings — plaintext SQL connection strings in Web.config, no managed identity support API surface changes — Global.asax → Program.cs minimal hosting, System.Web.Mvc → Microsoft.AspNetCore.Mvc The assessment is not a generic checklist. It reads your code — your controllers, your DbContext, your views — and maps a concrete modernization path. For this app, the key finding was clear: EF 6 on .NET Framework cannot support DefaultAzureCredential. The entire data layer needs to move to EF Core on modern .NET to unlock passwordless authentication. Phase 2: Code & Dependency Modernization This is where last year's experience ended and this year's began. The agent performed the actual modernization: Project structure: .csproj converted from legacy XML format to SDK-style targeting net10.0 Global.asax replaced with Program.cs using minimal hosting packages.config → NuGet PackageReference entries Data layer (the hard part): Entity Framework 6 → EF Core with Microsoft.EntityFrameworkCore.SqlServer DbContext rewritten with OnModelCreating fluent configuration System.Data.Entity → Microsoft.EntityFrameworkCore namespace throughout EF Core modernization generated from scratch Database seeding moved to a proper DbSeeder pattern with MigrateAsync() Identity: ASP.NET Membership → ASP.NET Core Identity with ApplicationUser, ApplicationDbContext Cookie authentication configured through ConfigureApplicationCookie Security (the whole trigger for this modernization): Azure.Identity + DefaultAzureCredential integrated in Program.cs Azure Key Vault configuration provider added via Azure.Extensions.AspNetCore.Configuration.Secrets Connection strings use Authentication=Active Directory Default — no passwords anywhere Application Insights wired through OpenTelemetry Views: Razor views updated from MVC 5 helpers to ASP.NET Core Tag Helpers and conventions _Layout.cshtml and all partials migrated The code changes touched every layer of the application. This is not a find-and-replace — it's a structural rewrite that maintains functional equivalence. Phase 3: Local Testing After modernization, the app builds, runs locally, and connects to a local SQL Server (or SQL in a container). EF Core modernizations apply cleanly, the seed data loads, and you can browse albums, add to cart, and check out. The identity system works. The Key Vault integration gracefully skips when KeyVaultName isn't configured — meaning local dev and Azure use the same Program.cs with zero code branches. Phase 4: AZD UP and Deployment to Azure The agent also generates the deployment infrastructure: azure.yaml — AZD service definition pointing to the Dockerfile, targeting Azure Container Apps Dockerfile — Multi-stage build using mcr.microsoft.com/dotnet/sdk:10.0 and aspnet:10.0 infra/main.bicep — Full IaaC including: Azure Container Apps with system + user-assigned managed identity Azure SQL Server with Azure AD-only authentication (no SQL auth) Azure Key Vault with RBAC, Secrets Officer role for the managed identity Container Registry with ACR Pull role assignment Application Insights + Log Analytics All connection strings injected as Container App secrets — using Active Directory Default, not passwords One command: AZD UP Provisions everything, builds the container, pushes to ACR, deploys to Container Apps. The app starts, runs MigrateAsync() on first boot, seeds the database, and serves traffic. Managed identity handles all auth to SQL and Key Vault. No credentials stored anywhere. What Changed in a Year Early 2025 Now Assessment Available Available Automated code modernization Semi-manual ✅ Full modernization agent Infrastructure generation Semi-manual ✅ Bicep + AZD generated Time to complete Weeks ✅ Hours The technology didn't just improve incrementally. The gap between "assessment" and "done" collapsed. A year ago, knowing what to do and being able to do it were very different things. Now they're the same step. Who This Is For If you have a .NET Framework app sitting on a backlog because "the modernization is too expensive" — revisit that assumption. The process changed. GitHub Copilot app modernization helps you rewrite your data layer, generates your infrastructure, and gets you to azd up. It can help you generate tests to increase your code coverage. If you have some feature requests – or – if you want to further optimize the code for scale – bring your requirements or logs or profile traces, you can take care of all of that during the modernization process. MVC Music Store went from .NET Framework 4.0 with Entity Framework 6 and plaintext SQL credentials to .NET 10 on Azure Container Apps with managed identity, Key Vault, and zero secrets in code. In an afternoon. That backlog item might be a lunch break now 😊. Really. Find your legacy apps and try it yourself. Next steps Modernize your .Net or Java apps with GitHub Copilot app modernization – https://aka.ms/ghcp-appmod Open your legacy application in Visual Studio or Visual Studio Code to start the process Deploy to Azure Container Apps https://aka.ms/aca/start390Views0likes1CommentA Practical Path Forward for Heroku Customers with Azure
On February 6, 2026, Heroku announced it is moving to a sustaining engineering model focused on stability, security, reliability, and ongoing support. Many customers are now reassessing how their application platforms will support today’s workloads and future innovation. Microsoft is committed to helping customers migrate and modernize applications from platforms like Heroku to Azure.213Views0likes0CommentsBuild PowerShell as "framework-dependent"
Before I start a time expensive and maybe unsuccessful attempt: Is it relatively easily possible to compile PowerShell from the source and make it "framework-dependent" instead of "self-contained"? In doing so, PowerShell could be de-coupled from the .NET runtime (which is most probably already installed), and maybe an even newer runtime version could be used (currently, PowerShell has no .NET 10 packed and I have to wait for a release that supports it)...97Views0likes1CommentEdm Model Generation Fails
Using an Azure ASP.NET MVC API from a Maui app, I am encountering the following error in the app when attempting to access the API. A few days ago, the initalization was working properly. The cloud app has been under further development, but the base api code has not been modified, only the response from the endpoints. The latest release NuGets are in use. What elements are being sought? System.TypeInitializationException: The type initializer for 'GeneratedEdmModel' threw an exception. ---> System.InvalidOperationException: Sequence contains no elements at System.Linq.ThrowHelper.ThrowNoElementsException() at System.Linq.Enumerable.First[TSource](IEnumerable`1 source) at SentryCloud.Models.Container.GeneratedEdmModel.CreateXmlReader()71Views0likes0CommentsFix It Before They Feel It: Higher Reliability with Proactive Mitigation
What if your infrastructure could detect performance issues and fix them automatically—before your users even notice? This blog brings that vision to life using Azure SRE Agent, an AI-powered autonomous agent that monitors, detects, and remediates production issues in real-time. 💡 The magic: Zero human intervention required. The agent handles detection, diagnosis, remediation, and reporting—all autonomously. 📺 Watch the Demo This content was presented at .NET Day 2025. Watch the full session to see Azure SRE Agent in action: 🎬 Fix it before they feel it - .NET Day 2025 🎯 What You'll See in This Demo Watch as we intentionally deploy "bad" code to production and observe how the SRE Agent: Detects the degradation — Compares live response times against learned baselines Takes autonomous action — Executes a slot swap to roll back to healthy code Communicates the incident — Posts to Teams and creates a GitHub issue Generates reports — Summarizes deployment metrics for stakeholders 🚀 Key Capabilities Capability What It Shows Proactive Baseline Learning Agent learns normal response times and stores them in a knowledge base Real-time Anomaly Detection Instant comparison of current vs. baseline metrics Autonomous Remediation Agent executes Azure CLI commands to swap slots without human approval Cross-platform Communication Automatic Teams posts and GitHub issue creation Incident Reporting End-of-day email summaries with deployment health metrics Architecture Overview The solution uses Azure SRE Agent with three specialized sub-agents working together: Components Application Layer: .NET 9 Web API running on Azure App Service Application Insights for telemetry collection Azure Monitor Alerts for incident triggers Azure SRE Agent: AvgResponseTime Sub-Agent: Captures baseline metrics every 15 minutes, stores in Knowledge Store DeploymentHealthCheck Sub-Agent: Triggered by deployment alerts, compares metrics to baseline, auto-remediates DeploymentReporter Sub-Agent: Generates daily summary emails from Teams activity External Integrations: GitHub (issue creation, semantic code search, Copilot assignment) Microsoft Teams (deployment summaries) Outlook (summary reports) What the SRE Agent Does When a deployment occurs, the SRE Agent autonomously performs the following actions: 1. Health Check (DeploymentHealthCheck Sub-Agent) When a slot swap alert fires, the agent: Queries App Insights for current response times Retrieves the baseline from the Knowledge Store Compares current performance against baseline If degradation > 20%: Executes rollback and creates GitHub issue If healthy: Posts confirmation to Teams Healthy Deployment - No Action Needed (Teams Post): The agent confirms the deployment is healthy — response time (22ms) is 80% faster than baseline (116ms). Degraded Deployment - Automatic Rollback (Teams Post): The agent detects +332% latency regression (212ms vs 116ms baseline), executes a slot swap to rollback, and creates GitHub Issue. 2. Daily Summary (DeploymentReporter Sub-Agent) Every 24 hours, the reporter agent: Reads all Teams deployment posts from the last 24 hours Aggregates deployment metrics Sends an executive summary email Daily Summary (Outlook Email): The daily report shows 9 deployments, 6 healthy, 3 rollbacks, and 3 GitHub issues created — complete with response time details and issue links. Demo Flow View Step-by-Step Instructions → Step Action Step 1 Deploy Infrastructure + Applications Step 2 Create Sub-Agents, Triggers & Schedules Step 3 Swap bad code, watch agent remediate Setting Up the Demo Prerequisites Azure subscription with Contributor access Azure CLI installed and logged in (az login) .NET 9.0 SDK PowerShell 7.0+ Step 1: Deploy Infrastructure cd scripts .\1-setup-demo.ps1 -ResourceGroupName "sre-demo-rg" -AppServiceName "sre-demo-app-12345" This script will: Prompt for Azure subscription selection Deploy Azure infrastructure (App Service, App Insights, Alerts) Build and deploy healthy code to production Build and deploy problematic code to staging Full Setup Instructions → Step 2: Configure Azure SRE Agent Navigate to Azure SRE Agents Portal Sub Agent builder tab and create three sub-agents: Sub-Agent Purpose Tools Used AvgResponseTime Captures baseline response time metrics QueryAppInsightsByAppId, UploadKnowledgeDocument DeploymentHealthCheck Detects degradation and executes remediation SearchMemory, QueryAppInsights, PostTeamsMessage, CreateGithubIssue, Az CLI commands DeploymentReporter Generates deployment summary reports GetTeamsMessages, SendOutlookEmail Creating Each Sub-Agent In the Github links below you can find gif images that capture the creation flow AvgResponseTime + Baseline Task: Detailed Instructions → DeploymentHealthCheck + Swap Alert: Detailed Instructions → DeploymentReporter + Reporter Task: Detailed Instructions → Step 3: Run the Demo .\2-run-demo.ps1 This triggers the following flow: Slot Swap Occurs (demo script) ▼ Activity Log Alert Fires ▼ Incident Trigger Activated ▼ DeploymentHealthCheck Agent Runs ─ Queries current response time from App Insights ─ Retrieves baseline from knowledge store ─ Compares (if >20% degradation) ─ Executes: az webapp deployment slot swap ─ Creates GitHub issue (if degraded) ─ Posts to Teams channel Full Demo Instructions → Demo Timeline Time Event 0:00 Run 2-run-demo.ps1 0:30 Swap staging → production (bad code deployed) 1:00 Production now slow (~1500ms vs ~50ms baseline) ~5:00 Slot Swap Alert fires ~5:04 Agent executes slot swap (rollback) ~5:30 Production restored to healthy state ~6:00 Agent posts to Teams, creates GitHub issue How the Performance Toggle Works The app has a compile-time toggle in ProductsController.cs: private const bool EnableSlowEndpoints = false; // false = fast, true = slow The setup script creates two versions: Production: EnableSlowEndpoints = false → ~50ms responses Staging: EnableSlowEndpoints = true → ~1500ms responses (artificial delay) Get Started 🔗 Full source code and instructions: github.com/microsoft/sre-agent/samples/proactive-reliability 🔗 Azure SRE Agent documentation: https://learn.microsoft.com/en-us/azure/sre-agent/ Technology Stack Framework: ASP.NET Core 9.0 Infrastructure: Azure Bicep Monitoring: Application Insights + Log Analytics Automation: Azure SRE Agent Scripts: PowerShell 7.0+ Tags: Azure, SRE Agent, DevOps, Reliability, .NET, App Service, Application Insights, Autonomous Remediation584Views0likes1Comment