microsoft/migrating-azure-functions-to-v2
> Migrates Azure Functions projects from legacy HostBuilder or in-process model to the modern Version 2.x pattern using IHostApplicationBuilder and Application Insights. Use when upgrading Azure Functions to isolated worker V2, replacing HostBuilder with FunctionsApplication.CreateBuilder, or adding Application Insights telemetry. Triggers for project files (.csproj, .vbproj, .fsproj) with Microsoft.Azure.Functions.Worker or Microsoft.NET.Sdk.Functions packages, and Program.cs files using HostBuilder patterns.
npx skills add https://github.com/microsoft/upgrade-agent-plugins --skill migrating-azure-functions-to-v2
Migrate Azure Functions projects to the Version 2.x hosting pattern (IHostApplicationBuilder via FunctionsApplication.CreateBuilder), replacing the legacy HostBuilder or in-process model, and enabling Application Insights telemetry.
> Related skill: For migrating from in-process Startup hooks to the isolated worker model first, use migrating-azure-functions-startup.
Two migration scenarios:
HostBuilder to V2Reference: https://aka.ms/AAyl34o
Track migration progress:
Migration Progress:
- [ ] Phase 1: Identify current model
- [ ] Phase 2: Planning
- [ ] Phase 3, Step 1: Update package references
- [ ] Phase 3, Step 2: Create or update Program.cs
- [ ] Phase 3, Step 3: Update function signatures
- [ ] Phase 3, Step 4: Update dependency injection
- [ ] Phase 3, Step 5: Update host.json
Package references in the project file:
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.x.x" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Http" Version="3.x.x" />
Function code pattern:
public class MyFunctions
{
[FunctionName("MyHttpFunction")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req,
ILogger log)
{
// Function code
}
}
Key indicator: In-process apps do NOT have a Program.cs file (or have minimal one)
Package references in the project file:
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.x.x" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.x.x" />
Program.cs pattern:
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices((context, services) =>
{
// Service registrations here
})
.Build();
host.Run();
Key indicators:
new HostBuilder()ConfigureServices((context, services) => { ... })context.ConfigurationReview function signatures:
Check dependency injection:
ExecutionContext or ILogger parametersDocument service configuration:
Examine current Program.cs:
ConfigureServicescontext.ConfigurationVerify function signatures:
[Function] attribute (not [FunctionName])Check package versions:
Verify Application Insights setup:
host.json settingsDetermine ASP.NET Core integration:
ConfigureFunctionsWebApplication() if the project needs ASP.NET Core middleware pipeline (e.g., custom middleware, model binding). Otherwise use ConfigureFunctionsWorkerDefaults() for simpler setups.For In-Process Projects (to Isolated V2):
Remove:
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.x.x" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Http" Version="3.x.x" />
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.x.x" />
Add:
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="2.0.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.2.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.0.0" />
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
For Legacy Isolated Projects (Upgrade to V2):
Update:
<!-- Before -->
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.x.x" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.x.x" />
<!-- After -->
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="2.0.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.0" />
Add if not present:
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.0.0" />
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
For In-Process Projects: Create New Program.cs
In-process projects typically don't have Program.cs. Create one in project root.
Standard Functions (without ASP.NET Core integration):
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = FunctionsApplication.CreateBuilder(args);
builder.ConfigureFunctionsWorkerDefaults();
// Enable Application Insights telemetry
builder.Services
.AddApplicationInsightsTelemetryWorkerService()
.ConfigureFunctionsApplicationInsights();
// Add service registrations
// Example:
// builder.Services.AddSingleton<IMyService, MyService>();
// builder.Services.AddHttpClient();
// Access configuration directly
// var connectionString = builder.Configuration["ConnectionString"];
// builder.Services.AddSingleton<IDatabase>(new Database(connectionString));
builder.Build().Run();
With ASP.NET Core integration:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = FunctionsApplication.CreateBuilder(args);
builder.ConfigureFunctionsWebApplication(); // Use this for ASP.NET Core integration
// Enable Application Insights telemetry
builder.Services
.AddApplicationInsightsTelemetryWorkerService()
.ConfigureFunctionsApplicationInsights();
// Add service registrations
builder.Build().Run();
Important: FunctionsApplication.CreateBuilder replaces both Host.CreateDefaultBuilder() and new HostBuilder() because V2 requires the IHostApplicationBuilder interface for proper integration with the Functions runtime.
For Legacy Isolated Projects: Migrate Existing Program.cs
Transform from legacy pattern to Version 2.x.
Before (Legacy HostBuilder):
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices((context, services) =>
{
services.AddSingleton<IMyService, MyService>();
services.AddHttpClient();
var connectionString = context.Configuration["ConnectionString"];
services.AddSingleton<IDatabase>(new Database(connectionString));
})
.Build();
host.Run();
After (Version 2.x IHostApplicationBuilder):
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = FunctionsApplication.CreateBuilder(args);
builder.ConfigureFunctionsWorkerDefaults();
// Enable Application Insights telemetry
builder.Services
.AddApplicationInsightsTelemetryWorkerService()
.ConfigureFunctionsApplicationInsights();
// Migrate service registrations (no ConfigureServices callback)
builder.Services.AddSingleton<IMyService, MyService>();
builder.Services.AddHttpClient();
// Configuration accessed directly via builder.Configuration
var connectionString = builder.Configuration["ConnectionString"];
builder.Services.AddSingleton<IDatabase>(new Database(connectionString));
builder.Build().Run();
Key migration changes:
new HostBuilder() with FunctionsApplication.CreateBuilder(args)ConfigureServices((context, services) => { ... }) callback wrapperbuilder.Services instead of callback services parameterbuilder.Configuration instead of context.Configurationbuilder.Build().Run() instead of host.Run()If migrating from in-process, update function signatures:
Before (In-Process):
[FunctionName("MyHttpFunction")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req,
ILogger log)
{
log.LogInformation("Processing request");
return new OkObjectResult("Success");
}
After (Isolated V2):
[Function("MyHttpFunction")]
public async Task<HttpResponseData> Run(
[HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequestData req)
{
_logger.LogInformation("Processing request");
var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteStringAsync("Success");
return response;
}
Key changes:
[FunctionName] → [Function]HttpRequest → HttpRequestDataIActionResult → HttpResponseDataILogger injected via constructor instead of parameterreq.CreateResponse() to create responsesBefore (In-Process with Startup.cs):
[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddSingleton<IMyService, MyService>();
}
}
After (Isolated V2 in Program.cs):
var builder = FunctionsApplication.CreateBuilder(args);
builder.Services.AddSingleton<IMyService, MyService>();
builder.Build().Run();
For V2, Application Insights is configured via code. Remove Application Insights configuration from host.json if present:
Before:
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true
}
}
}
}
After:
{
"version": "2.0"
}
Application Insights is now configured via:
builder.Services
.AddApplicationInsightsTelemetryWorkerService()
.ConfigureFunctionsApplicationInsights();
Take microsoft/migrating-azure-functions-to-v2 from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.