Azure Functions で C# の .NET アプリを運用している場合、いま優先して確認すべきなのは「その関数アプリが in-process model のまま残っていないか」です。Microsoft は .NET の in-process model について、2026年11月10日にサポート終了すると案内しており、継続してフルサポートを受けるには isolated worker model への移行が必要です。(Microsoft Learn)
今回の「Migrate C# apps from the in-process model to the isolated worker model」で押さえるべきポイントは、単なる .NET バージョンアップではありません。.csproj、NuGet パッケージ、Program.cs、関数シグネチャ、FUNCTIONS_WORKER_RUNTIME、デプロイスロットまで含めた移行作業です。特に本番環境では、コードと Azure 側のランタイム設定がずれるとエラー状態になるため、ステージングスロットで検証してから切り替える運用が重要です。(Microsoft Learn)
まず確認すべき結論:対象は dotnet の in-process 関数アプリ
今回の移行対象は、Azure Functions の C# アプリのうち、in-process model で動いている .NET 関数アプリです。Azure 側のアプリ設定で FUNCTIONS_WORKER_RUNTIME が dotnet になっている場合は、基本的に in-process model と見て棚卸し対象にします。日本マイクロソフトの Japan PaaS Support Team Blog でも、Azure Portal の「環境変数」>「アプリ設定」で FUNCTIONS_WORKER_RUNTIME の値を確認する方法が案内されています。(Azure)
一方、すでに FUNCTIONS_WORKER_RUNTIME が dotnet-isolated の関数アプリは、今回の「in-process から isolated worker へ移行する」対象ではありません。ただし、.NET 8 などターゲットフレームワーク自体のサポート期限は別途確認が必要です。
2026年7月上旬の更新ポイント
Microsoft Learn の GitHub 履歴では、2026年7月2日のコミットで「Functions runtime 4.x の in-process model では .NET 6 または .NET 8」だった記述が、「.NET 8」に整理されています。日本時間では7月3日として扱われる更新情報として参照される可能性がありますが、実務上の意味は明確です。Functions runtime 4.x で in-process model を使い続ける前提では、.NET 8 が最後の実質的な確認対象になります。(GitHub)
| 確認項目 | 更新・確認すべき内容 | 実務上の対応 |
|---|---|---|
| in-process のサポート期限 | 2026年11月10日にサポート終了 | 期限前に isolated worker model へ移行計画を作る |
| Functions runtime 4.x の in-process | .NET 8 をターゲットにする記述へ整理 | .NET 6 in-process は移行・更新の優先度を上げる |
| isolated worker model | .NET LTS、STS、.NET Framework をより柔軟に扱える | 新規開発は isolated worker model を前提にする |
| Azure 側の設定 | FUNCTIONS_WORKER_RUNTIME=dotnet-isolated へ変更が必要 | コードのデプロイと設定変更を同時に管理する |
| 本番反映 | ペイロードとランタイム設定の不一致でエラー状態になる可能性 | ステージングスロットで検証し、スワップで反映する |
Microsoft Learn の比較表では、isolated worker model は .NET の LTS、STS、.NET Framework をサポートする一方、in-process model は LTS のみで .NET 8 までと説明されています。また、in-process model のサポート終了日は 2026年11月10日です。(Microsoft Learn)
in-process model と isolated worker model の違い
in-process model では、関数コードが Azure Functions host と同じプロセス内で動作します。これに対して isolated worker model では、関数コードが別の .NET worker process として実行されます。Microsoft Learn では、この違いを「関数コードが Functions host process と同じプロセスで動くか、別の .NET worker process で動くか」と整理しています。(Microsoft Learn)
この違いは、単に実行方式が変わるだけではありません。依存関係、起動処理、ログ、HTTP トリガー、バインディング、Application Insights の扱いに影響します。特に実務で大きいのは、Startup.cs や FunctionsStartup に寄せていた初期化処理を Program.cs に移す点です。
| 観点 | in-process model | isolated worker model |
|---|---|---|
| 実行プロセス | Functions host と同じプロセス | 別の .NET worker process |
| 主要パッケージ | Microsoft.NET.Sdk.Functions | Microsoft.Azure.Functions.Worker、Worker.Sdk |
| DI・起動処理 | FunctionsStartup を利用する構成が多い | Program.cs の HostBuilder で構成 |
| ログ | 関数メソッド引数の ILogger を使う実装が多い | DI による ILogger<T> が推奨される |
| ミドルウェア | 利用範囲が限定的 | .NET の一般的な構成に近い形で扱える |
| 将来の .NET 対応 | .NET 8 まで | .NET 8、.NET 9、.NET 10 などの対応を確認して選べる |
新規に Azure Functions の C# アプリを作るなら、原則として isolated worker model を選ぶのが安全です。既存アプリの場合は、単純な設定変更ではなく、コード変更を含む移行作業として扱う必要があります。
影響範囲:どのアプリを優先して確認するべきか
優先度が高いのは、次の条件に当てはまる関数アプリです。
- Azure Functions runtime 4.x で動作している C# アプリ
- アプリ設定の
FUNCTIONS_WORKER_RUNTIMEがdotnet .csprojにMicrosoft.NET.Sdk.FunctionsがあるMicrosoft.Azure.WebJobs.*系のパッケージや namespace を使っているFunctionName属性、関数引数のILogger、IAsyncCollector<T>、IBinderを使っている- Timer、Queue、Blob、Cosmos DB、Service Bus、Event Hubs、Durable Functions などのバインディングを多用している
Microsoft Learn では、サブスクリプション内で in-process model の関数アプリを見つけるための Azure PowerShell スクリプトが示されています。複数サブスクリプションや複数リージョンで運用している組織では、1つの本番アプリだけでなく、検証環境、DR 環境、停止中のアプリ、スロット、IaC テンプレートまで含めて確認するのが現実的です。(Microsoft Learn)
Set-AzContext -Subscription '<SUBSCRIPTION_ID>'
Get-AzFunctionApp |
Where-Object { $_.Runtime -eq 'dotnet' } |
Select-Object Name, ResourceGroup, Location, Runtime
この棚卸しで見落としやすいのは、普段あまり更新していないバッチ系の関数です。HTTP API は監視やデプロイ頻度が高いため発見しやすい一方、Timer trigger や Queue trigger の関数は「動いているから触っていない」状態になりがちです。
ターゲット .NET バージョンの選び方
公式ガイドでは、Functions runtime 4.x の isolated worker model でサポートされる .NET バージョンとして、.NET 10 LTS、.NET 9 STS、.NET 8 LTS、.NET Framework 4.8 が示されています。一方で、ガイド内の具体的な移行例は .NET 8 と .NET Framework 4.8 が中心で、.NET 10 や .NET 9 をターゲットにする場合は .NET 8 の例を適用して調整する必要があります。(Microsoft Learn)
| 選択肢 | 向いているケース | 注意点 |
|---|---|---|
| .NET 8 isolated | 既存の in-process .NET 8 から短期で移行したい | .NET 8 自体のサポート期限も確認する |
| .NET 10 isolated | 長期保守を見据えて更新したい | 開発環境、CI/CD、ホスティングプランの対応を確認する |
| .NET Framework 4.8 isolated | .NET Framework 依存が残る既存資産を段階移行したい | 将来の .NET モダナイズ計画を別途立てる |
| .NET 9 isolated | STS 前提で検証・短期利用したい | 長期運用には LTS の方が判断しやすい |
注意したいのは、.NET のバージョン選定と Functions の実行モデル選定を分けて考えることです。「.NET 8 に上げたから完了」ではなく、「isolated worker model で動いているか」まで確認しなければ、in-process model のサポート終了リスクは残ります。
また、Microsoft Learn の比較表では .NET 10 アプリを Linux の Consumption plan では実行できず、Linux で実行する場合は Flex Consumption plan の利用を検討する旨も示されています。グローバル展開で Linux Consumption plan を使っている場合は、.NET バージョンだけでなくホスティングプランも移行設計に含めるべきです。(Microsoft Learn)
移行で変更が必要になる主な設定
.csproj は「ライブラリ」から「実行可能アプリ」に近い構成へ変わる
isolated worker model では、プロジェクトファイルに <OutputType>Exe</OutputType> を追加します。これは、関数アプリが Functions host に読み込まれるライブラリではなく、独立した worker process として起動する構成になるためです。Microsoft Learn の .NET 8 向け手順では、TargetFramework を net8.0、AzureFunctionsVersion を v4 にし、Microsoft.NET.Sdk.Functions を isolated worker 用パッケージへ置き換える流れが示されています。(Microsoft Learn)
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
NuGet パッケージは WebJobs 系から Worker 系へ置き換える
in-process model で使っていた Microsoft.Azure.WebJobs.* 系の拡張パッケージは、isolated worker model では Microsoft.Azure.Functions.Worker.Extensions.* 系に置き換えます。Microsoft Learn では、Storage、Cosmos DB、Service Bus、Event Hubs、Event Grid、SignalR、Durable Functions など、代表的なバインディングごとの置き換えが整理されています。(Microsoft Learn)
| 利用している機能 | 見直すパッケージの例 | 移行時の確認ポイント |
|---|---|---|
| Core SDK | Microsoft.NET.Sdk.Functions | Microsoft.Azure.Functions.Worker と Worker.Sdk へ置き換える |
| Storage | Microsoft.Azure.WebJobs.Extensions.Storage | Blob、Queue、Table の Worker Extensions を確認する |
| Cosmos DB | Microsoft.Azure.WebJobs.Extensions.CosmosDB | Worker.Extensions.CosmosDB 系へ移行する |
| Service Bus | Microsoft.Azure.WebJobs.Extensions.ServiceBus | 拡張バージョン差による host.json 変更を確認する |
| Durable Functions | Microsoft.Azure.WebJobs.Extensions.DurableTask | Durable Functions 固有の移行差分を別途検証する |
| DI・Startup | Microsoft.Azure.Functions.Extensions | isolated worker では原則不要。Program.cs に統合する |
公式ガイドでは、isolated worker model のアプリに Microsoft.Azure.WebJobs.* namespace のパッケージや Microsoft.Azure.Functions.Extensions が残っている場合は削除すべきと説明されています。パッケージが残っていると、ビルドは通ってもバインディングや実行時の挙動で詰まることがあります。(Microsoft Learn)
Program.cs への移行で起動処理が変わる
isolated worker model では、Program.cs を追加し、HostBuilder で Functions worker、DI、Application Insights などを構成します。HTTP trigger を使う場合、公式ガイドでは ASP.NET Core integration を使う ConfigureFunctionsWebApplication() の例が示されています。(Microsoft Learn)
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services =>
{
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
})
.Build();
host.Run();
既存の Startup.cs や FunctionsStartup に DI 登録、設定読み込み、クライアント生成、ログ設定を書いていた場合は、その内容を Program.cs の .ConfigureServices() や HostBuilder の構成へ移します。移行後は FunctionsStartup 属性と対象クラスを削除できます。(Microsoft Learn)
実務では、この段階で「アプリ起動時に読み込む設定」と「Functions host がトリガーやバインディング解決に使う設定」を分けて確認する必要があります。公式ガイドでは、HostBuilder に追加したカスタム構成ソースはプロジェクト内のコードには適用されるものの、プラットフォームが必要とするトリガーやバインディング設定はアプリ設定、Key Vault 参照、App Configuration 参照などで提供する必要があると説明されています。(Microsoft Learn)
関数コードで変更が必要なポイント
FunctionName は Function に変更する
in-process model で使っていた [FunctionName("...")] は、isolated worker model では [Function("...")] に変更します。属性名は変わりますが、関数名を指定する役割は同じです。(Microsoft Learn)
[Function("HttpTriggerCSharp")]
public IActionResult Run(
[HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req)
{
// 処理
}
ILogger はメソッド引数ではなく DI で受ける
in-process model では、関数メソッドの引数に ILogger log を置く実装がよく使われていました。isolated worker model では、コンストラクターで ILogger<T> を受け取る形に変更するのが基本です。(Microsoft Learn)
public class MyFunction
{
private readonly ILogger<MyFunction> _logger;
public MyFunction(ILogger<MyFunction> logger)
{
_logger = logger;
}
[Function("MyFunction")]
public void Run([TimerTrigger("0 */5 * * * *")] TimerInfo timer)
{
_logger.LogInformation("Function executed.");
}
}
この変更は、単に書き方を変えるだけではありません。テストしやすくなり、関数クラス単位で依存関係を整理しやすくなります。一方で、静的クラス・静的メソッド前提の実装は見直しが必要です。
トリガーとバインディング属性を見直す
公式ガイドでは、トリガー名は多くの場合そのままですが、input binding は Input、output binding は Output が付く傾向があると説明されています。たとえば in-process model の [Blob(...)] は、isolated worker model では [BlobOutput(...)] のように変更します。(Microsoft Learn)
| 変更箇所 | 例 | 注意点 |
|---|---|---|
| namespace | Microsoft.Azure.WebJobs | Microsoft.Azure.Functions.Worker へ変更 |
| 関数属性 | [FunctionName("X")] | [Function("X")] へ変更 |
| Input binding | CosmosDB | CosmosDBInput などに変更される場合がある |
| Output binding | Queue、Blob | QueueOutput、BlobOutput などを確認 |
| 出力の扱い | IAsyncCollector<T> | T[]、戻り値、複数出力クラス、SDK クライアントを検討 |
| 動的バインディング | IBinder | SDK クライアント注入などに置き換える |
出力バインディングは、関数の引数リストから戻り値や戻り値用のクラスへ移すケースがあります。複数出力がある場合は、出力ごとにプロパティを持つクラスを作り、各プロパティに binding 属性を付ける設計が分かりやすくなります。
local.settings.json と Azure のアプリ設定
ローカル実行では、local.settings.json の FUNCTIONS_WORKER_RUNTIME を dotnet-isolated に変更します。AzureWebJobsStorage の値は環境によって異なりますが、移行そのもののために変更する必要はないとされています。(Microsoft Learn)
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
}
}
Azure 側でも、対象の Function App またはステージングスロットのアプリ設定で FUNCTIONS_WORKER_RUNTIME を dotnet-isolated に変更します。ターゲット .NET バージョンも変える場合は、スタック構成の更新も必要です。さらに、CI/CD や IaC でこの設定を管理している場合は、Azure Portal だけを変更しても次回デプロイで戻される可能性があります。(Microsoft Learn)
host.json と Application Insights の注意点
公式ガイドでは、移行そのもののために host.json の変更は必須ではないとされています。ただし、Application Insights のログ構成を host.json に寄せていた場合は注意が必要です。isolated worker model では、host.json が制御するのは Functions host runtime 由来のログであり、アプリケーションコード側のログフィルタリングは Program.cs 側で構成する必要があります。(Microsoft Learn)
移行後に「ログが増えた」「特定カテゴリのログレベルが変わった」と見える場合、アプリの不具合ではなくログ構成の差分が原因のことがあります。Application Insights のコストにも影響するため、本番移行前に検証環境でサンプリング、ログレベル、カスタムログの出力量を確認しておくべきです。
本番移行はステージングスロットで行う
Azure 上の Function App を isolated worker model に更新する際は、コードのデプロイとランタイム設定の変更をセットで扱う必要があります。公式ガイドでは、どちらか一方だけを実施するとアプリがエラー状態になるため、ステージングスロットを使うことが推奨されています。設定変更とデプロイの両方でプロセス再起動が発生する点も重要です。(Microsoft Learn)
| 手順 | 作業内容 | 確認ポイント |
|---|---|---|
| 事前準備 | ステージングスロットを作成 | 本番と同等のアプリ設定・接続先を確認 |
| 設定変更 | ステージング側で FUNCTIONS_WORKER_RUNTIME=dotnet-isolated に変更 | この設定は slot setting にしない |
| コード反映 | 移行済みプロジェクトをステージングへデプロイ | 起動エラー、バインディングエラー、DI エラーを確認 |
| 動作確認 | HTTP、Timer、Queue、Service Bus などを検証 | 本番相当データで副作用を起こさないよう注意 |
| スワップ | ステージングから本番へ slot swap | 本番に中間的なエラー状態を持ち込まない |
| 事後確認 | 本番ログ、Application Insights、メトリックを確認 | 失敗率、実行時間、キュー滞留、コールドスタートを確認 |
特にグローバル向けサービスでは、リージョンごとに切替タイミングを分ける、DR 側も同じ構成にする、トラフィックが少ない時間帯で swap する、といった運用上の配慮が必要です。コード移行が終わっても、スロット、環境変数、Key Vault 参照、App Configuration 参照、CI/CD 変数が一致していなければ、本番だけ失敗することがあります。
移行で失敗しやすいポイント
| 失敗しやすいポイント | 起きる問題 | 対策 |
|---|---|---|
FUNCTIONS_WORKER_RUNTIME だけ変更する | デプロイ済みコードと実行モデルが合わずエラーになる | コードと設定を同じリリース単位で変更する |
Microsoft.Azure.WebJobs.* が残る | バインディングやビルドで不整合が出る | Worker.Extensions.* 系へ置き換える |
Startup.cs の処理を移し忘れる | DI、設定、クライアント生成が動かない | Program.cs に登録処理を移す |
ログ設定を host.json だけで管理する | アプリ側ログのレベルが想定と異なる | Program.cs でログフィルタリングを構成する |
IAsyncCollector<T> をそのまま使う | isolated worker model で想定通り動かない | 戻り値、配列、SDK クライアントに置き換える |
| CI/CD の設定を更新しない | 手動変更が次回デプロイで巻き戻る | pipeline、Bicep、ARM、Terraform も更新する |
| Durable Functions を通常の関数と同じ扱いで移す | Durable 固有の差分で失敗する | Durable Functions の移行ドキュメントも確認する |
実務では、ビルドエラーを解消しただけでは移行完了とは言えません。トリガーが発火するか、バインディングが期待通り解決されるか、失敗時のリトライや dead-letter の挙動が変わっていないかまで確認する必要があります。
管理者が確認すべきチェックリスト
移行計画を立てる管理者は、開発チームに「isolated worker model に直しておいて」と依頼するだけでは不十分です。対象アプリ、期限、影響、検証範囲、リリース方法を明確にしておく必要があります。
| 確認項目 | チェック内容 |
|---|---|
| 対象アプリ | FUNCTIONS_WORKER_RUNTIME=dotnet の関数アプリを全サブスクリプションで抽出したか |
| 実行環境 | Functions runtime、OS、ホスティングプラン、リージョンを確認したか |
| .NET バージョン | .NET 8、.NET 10、.NET Framework 4.8 のどれを選ぶか決めたか |
| コード差分 | .csproj、パッケージ、Program.cs、関数属性、ログ、バインディングを見直したか |
| 設定差分 | FUNCTIONS_WORKER_RUNTIME、スタック構成、Key Vault 参照、App Configuration 参照を確認したか |
| CI/CD | GitHub Actions、Azure DevOps、IaC テンプレート、環境変数を更新したか |
| 検証 | ローカル、ステージング、本番スワップ後の確認項目を定義したか |
| 監視 | Application Insights、アラート、ログ量、失敗率、実行時間を確認したか |
| 期限 | 2026年11月10日より前に本番移行できる計画になっているか |
サポート終了後も in-process model のアプリが直ちに停止するとは限りません。ただし、日本マイクロソフトの案内では、2026年11月10日以降も利用自体は可能でも、Microsoft からのセキュリティおよび機能アップデートは受けられなくなると説明されています。業務システムや顧客向けサービスでは、「動くかどうか」ではなく「サポートされる状態かどうか」で判断するべきです。(Azure)
いま取るべき次のアクション
まずは、サブスクリプション全体で FUNCTIONS_WORKER_RUNTIME=dotnet の Function App を棚卸ししてください。次に、対象アプリごとにトリガー、バインディング、依存パッケージ、.NET バージョン、ホスティングプランを一覧化します。そのうえで、影響が小さいアプリから isolated worker model へ移行し、共通テンプレートや CI/CD の修正内容を標準化すると、複数アプリの移行を安全に進めやすくなります。
今回の更新ポイントは、「いつか .NET を上げる」ではなく「in-process model から脱却する期限が明確になっている」ことです。2026年11月10日までの残り期間を考えると、対象調査、移行方針、検証環境、本番切替手順を早めに固めることが、Azure Functions を安定運用するうえで最も重要です。

コメント