Timer trigger for Azure Functionsの変更点と確認すべき設定・移行ポイント

2026年5月20日時点の公式情報を前提に見ると、Timer trigger for Azure Functions(Azure Functionsのタイマートリガー)は、スケジュールに沿って関数を実行するためのトリガーです。今回まず押さえるべき結論は、既存のTimer triggerの書き方を一斉に変更するような破壊的変更ではなく、公式リファレンスから実践的なクイックスタートへの導線が強化され、運用時に見落としやすい設定確認の重要度が増したことです。MicrosoftDocsの履歴では、Timer triggerの記事にエンドツーエンド例へのリンクを追加する差分が確認できます。(Microsoft Learn)

特に確認すべきなのは、schedulerunOnStartupuseMonitorAzureWebJobsStorage、タイムゾーン、C#の実行モデルです。日次バッチ、定期集計、外部APIのポーリング、キャッシュ更新、監視ジョブをAzure Functionsで動かしている管理者・開発者は、この記事のチェック項目に沿って現在の設定を棚卸ししてください。

目次

Timer trigger for Azure Functionsで何が変わったのか

今回のポイントは「Timer triggerの仕様が大きく変わった」というより、「参照すべき公式情報の流れが整理された」と捉えるのが実務的です。

公式ドキュメントの差分では、Timer triggerのリファレンス記事から「Run scheduled tasks using Azure Functions」というクイックスタートへのリンクが追加されています。このクイックスタートは、azdを使ってTimer trigger関数を作成し、ローカル確認後にFlex Consumptionプラン上のFunction Appへデプロイする流れを扱っています。(GitHub)

観点変更・確認ポイント既存利用者への影響
ドキュメント導線Timer triggerリファレンスから、スケジュールタスク作成の実践的なクイックスタートへ移動しやすくなった新規構築や再設計時に、リファレンスだけでなくデプロイ手順まで確認しやすい
実装方法C#、JavaScript、TypeScript、Python、Java、PowerShellなど言語別の定義方法は継続して掲載既存コードを直ちに変更する必要は通常ない
デプロイ観点azd、Flex Consumption、マネージドID、Application Insightsなどを含む構成例が参照しやすくなった新規案件ではテンプレートベースの構築を検討しやすい
運用設定runOnStartupuseMonitor、ストレージ依存、タイムゾーン制約の確認が重要設定ミスによる予期しない実行、未実行、重複停止を防ぐ必要がある
移行観点C# in-processモデルはサポート終了予定が明記されているC#利用者は isolated worker model への移行計画が必要

要するに、今回の記事で見るべき本質は「Timer triggerの基本設定を改めて正しく理解し、最新のAzure Functions運用に合わせて設定・デプロイ・監視を見直すこと」です。

Timer triggerの基本:スケジュール実行に使うAzure Functionsのトリガー

Timer triggerは、指定したスケジュールに従って関数を実行する仕組みです。たとえば、次のような処理に向いています。

  • 毎朝9時に売上データを集計する
  • 5分ごとに外部APIから状態を取得する
  • 1時間ごとに期限切れデータを削除する
  • 毎日深夜にキャッシュや検索インデックスを更新する
  • 監視対象URLへ定期的にアクセスしてログを残す

HTTPトリガーのようにユーザー操作を待つのではなく、時刻や間隔を基準に自動実行される点が特徴です。Azure FunctionsのTimer triggerでは、主にNCRONTAB式を使ってスケジュールを定義します。NCRONTAB式は一般的なCRON式に近いものですが、秒を表すフィールドを先頭に持つ形式として説明されています。(Microsoft Learn)

{second} {minute} {hour} {day} {month} {day-of-week}

たとえば、5分ごとに実行する場合は次のように書きます。

0 */5 * * * *

最初の0は「0秒」を意味します。通常のLinux cronに慣れている人は、秒フィールドの有無で間違えやすいため注意が必要です。

管理者・開発者が最初に確認すべき設定

Timer trigger for Azure Functionsを運用している場合、最初に見るべき設定は次の6つです。どれも小さな設定に見えますが、本番環境では「予定時刻に動かない」「デプロイ時に想定外に動く」「スケールアウト時に片方しか動かない」といったトラブルにつながります。

設定・項目確認する内容実務上の判断基準
scheduleNCRONTAB式または一部条件でTimeSpanを指定しているか本番ではハードコードよりアプリ設定参照を優先する
runOnStartup起動時に即実行するか本番環境では原則false
useMonitorスケジュール監視を有効にするか1分以上の間隔なら既定でtrueだが、重要ジョブでは明示設定を検討
AzureWebJobsStorageホストストレージが正しく設定されているかスケールアウト調整に関わるため、接続・権限を必ず確認
タイムゾーンUTC基準か、WEBSITE_TIME_ZONEを使うかLinuxのFlex Consumption/Consumptionでは制約に注意
実行モデルC# in-processか isolated workerかC#は将来のサポート期限を見て移行計画を立てる

公式リファレンスでは、schedulerunOnStartupuseMonitorが主要な設定として説明されています。また、TimeSpanはApp Serviceプランで実行するFunction Appに限って使える点も明記されています。(Microsoft Learn)

scheduleはアプリ設定に外出しする

スケジュールをコードに直接書くと、実行時刻を変更するたびに再デプロイが必要になります。実務では、次のようにアプリ設定を参照する形にしておくと運用しやすくなります。

[TimerTrigger("%TIMER_SCHEDULE%")]

アプリ設定側には、たとえば次のような値を入れます。

0 */5 * * * *

この方法なら、開発環境では30秒ごと、本番環境では5分ごと、検証環境では1時間ごと、というように環境別にスケジュールを変えられます。公式クイックスタートでも、TIMER_SCHEDULElocal.settings.jsonValuesに設定する例が示されています。(Microsoft Learn)

runOnStartupは本番で安易に有効化しない

runOnStartuptrueにすると、Function Appのランタイム開始時に関数が実行されます。開発や検証では便利ですが、本番では注意が必要です。

公式ドキュメントでは、runOnStartupを本番環境でtrueにしないよう注意が示されています。Function Appの再起動、スケール、デプロイなどのタイミングで予期しない実行が発生し、従量課金環境ではコスト増につながる可能性があります。(Microsoft Learn)

たとえば、請求処理や通知送信のように「1回だけ実行されること」が重要な処理でrunOnStartupを有効にすると、デプロイやスケールのタイミングで重複処理が起きる恐れがあります。本番環境では、特別な理由がない限りfalseにしてください。

useMonitorは高頻度実行で既定値が変わる

useMonitorは、スケジュールの発生を記録して、Function Appの再起動後もスケジュールを維持しやすくするための設定です。公式リファレンスでは、繰り返し間隔が1分以上なら既定でtrue、1分に複数回実行されるスケジュールでは既定でfalseと説明されています。(Microsoft Learn)

高頻度のポーリング処理では、useMonitorを明示せずに使っていると、想定と違う挙動に見える場合があります。重要なジョブでは、既定値に任せず、設定の意図をコードレビューで確認できるようにしておくと安全です。

NCRONTAB式で失敗しやすいポイント

Timer trigger for Azure Functionsで最も多いミスは、CRON式の読み違いです。特に「秒フィールド」「UTC」「曜日指定」でつまずきやすくなります。

やりたいことNCRONTAB式注意点
5分ごとに実行0 */5 * * * *先頭の0は秒
毎時0分に実行0 0 * * * *1時間ごと
毎日9:30に実行0 30 9 * * *既定ではUTC基準
平日9:30に実行0 30 9 * * 1-5曜日指定の扱いを確認
30秒ごとに実行*/30 * * * * *高頻度実行ではコストとuseMonitorに注意

公式リファレンスでは、CRON式の既定タイムゾーンはUTCと説明されています。日本時間の9:30に実行したい場合、単純に0 30 9 * * *と書くとUTCの9:30、つまり日本時間では18:30になります。日本時間9:30に合わせるなら、UTC換算で0 30 0 * * *にするか、利用プランとOSが対応している場合にWEBSITE_TIME_ZONEを使います。(Microsoft Learn)

ただし、LinuxのFlex ConsumptionプランまたはConsumptionプランでは、WEBSITE_TIME_ZONETZが現在サポートされていないと説明されています。この条件に当てはまる場合は、タイムゾーン設定に頼らず、UTC基準でスケジュールを設計するのが安全です。(Microsoft Learn)

スケールアウト時の影響:複数インスタンスでも基本は1つだけ実行

Timer triggerは、Function Appが複数インスタンスにスケールアウトしても、同じTimer trigger関数が全インスタンスで同時に実行されるわけではありません。公式リファレンスでは、複数インスタンスにスケールアウトした場合でも、Timer trigger関数は1つのインスタンスだけで実行され、未完了の呼び出しが残っている場合は再度トリガーされないと説明されています。(Microsoft Learn)

これは、定期バッチの重複実行を避けるうえでは便利です。一方で、次のようなケースでは設計に注意が必要です。

ケース起こり得る問題対策
処理時間がスケジュール間隔を超える次の予定実行が始まらない、または遅延する処理を分割し、QueueやService Busに投入する
1分ごとのジョブで外部APIが遅い実行が詰まり、IsPastDueが発生しやすいタイムアウト、リトライ、並列度を見直す
複数のFunction Appで同じStorageを共有片方のTimer triggerしか動かない可能性ホストIDを明示的に分ける
ジョブの失敗時に即時再実行したいTimer trigger自体は失敗後に自動リトライしないアプリ側で再試行するか、Queue triggerなどに切り出す

Timer triggerはキュートリガーとは異なり、関数が失敗しても次のスケジュール時刻まで再実行されません。失敗時の再試行が業務上必須なら、Timer triggerの中で直接重い処理を完結させるより、Timer triggerは「起点」にして、実処理はQueue、Service Bus、Durable Functionsなどに渡す設計を検討してください。(Microsoft Learn)

AzureWebJobsStorageと権限を確認する

Timer triggerは、ローカルでAzure Functions Core Toolsを使って実行する場合を除き、BLOBストレージに暗黙的に依存します。スケールアウト時の調整にもBLOBストレージが使われ、ホストストレージであるAzureWebJobsStorage接続を通じてアクセスします。IDベース接続を使う場合、IDにはStorage Blob Data Ownerロールが必要と説明されています。(Microsoft Learn)

管理者が確認すべきポイントは次のとおりです。

確認項目見る場所判断基準
AzureWebJobsStorageFunction Appの構成、アプリ設定接続文字列またはIDベース接続が正しく設定されている
マネージドIDFunction AppのID設定有効化され、対象Storageへアクセスできる
RBACStorageアカウントのアクセス制御必要なロールが付与されている
共有Storage複数Function Appの構成同じホストIDを使っていない
監視Application Insights、Log stream実行時刻、失敗、IsPastDueを追える

特に、複数のFunction Appで同じStorageアカウントを共有している構成では、ホストIDの重複に注意してください。Timer triggerはストレージロックを使って1つのTimerインスタンスだけが動くようにするため、同じ識別構成を共有すると、意図せず片方だけが実行される可能性があります。(Microsoft Learn)

C#利用者はin-processモデルの移行を確認する

C#でTimer triggerを使っている場合は、実行モデルの確認も必要です。公式ドキュメントでは、C#のin-processモデルのサポートが2026年11月10日に終了すると案内され、完全なサポートのためにisolated worker modelへの移行が推奨されています。(Microsoft Learn)

既存コードが次のような形なら、in-processモデルである可能性があります。

[FunctionName("TimerTriggerCSharp")]
public static void Run([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer, ILogger log)
{
    log.LogInformation("Timer trigger executed.");
}

一方、isolated worker modelでは、[Function]属性やFunctionContextを使う構成になります。移行時は、Timer triggerのスケジュール式だけでなく、ロギング、DI、設定読み込み、例外処理、拡張機能パッケージの名前空間も一緒に確認してください。

移行の優先度が高いのは、次のようなFunction Appです。

優先度対象理由
請求、通知、データ更新など業務影響が大きいTimer trigger移行後の動作検証に時間が必要
複数のTimer triggerを持つFunction Appスケジュール、ログ、依存関係の確認範囲が広い
開発停止している古いC# Function Appサポート期限直前に対応するとリスクが高い
ポータル編集に依存しているC#スクリプトCI/CDや構成管理への移行も検討が必要
検証用、短期利用、削除予定のFunction App削除または統合も選択肢になる

新規構築ではクイックスタートの構成を参考にする

新しくTimer trigger for Azure Functionsを作る場合は、リファレンスだけを見てコードを書くより、公式クイックスタートの構成を参考にしたほうが安全です。クイックスタートでは、azd initでテンプレートからプロジェクトを作り、ローカルで確認した後、azd upでAzure上のFunction Appと関連リソースを作成・デプロイする流れが示されています。(Microsoft Learn)

クイックスタートで注目したいのは、単にTimer triggerのコード例を示しているだけでなく、Azure Storage、Application Insights、マネージドID、ネットワーク構成など、運用に必要な周辺リソースも含めている点です。公式記事では、Flex Consumptionプラン上にFunction Appを作成し、セキュアでスケーラブルなAzure Functionsデプロイの現在のベストプラクティスに従う構成として説明されています。(Microsoft Learn)

ただし、クイックスタートのサンプルには開発・検証向けの設定が含まれる場合があります。たとえば、すぐに動作確認しやすいようにrunOnStartupが有効な例があっても、本番では無条件に流用しないでください。公式クイックスタートでも、本番では予期しない実行を避けるためにrunOnStartupfalseにする旨が示されています。(Microsoft Learn)

移行・展開前のチェックリスト

既存のTimer triggerを見直す場合は、次の順で確認すると抜け漏れを減らせます。

| 手順 | 作業 | 確認内容 |
| -: | ——————- | ——————————————— |
| 1 | 対象Function Appを洗い出す | timerTriggerを使っている関数を一覧化する |
| 2 | スケジュールを確認する | NCRONTAB式、UTC基準、曜日指定、実行間隔を確認する |
| 3 | 設定値を外出しする | %TIMER_SCHEDULE%のようにアプリ設定化する |
| 4 | runOnStartupを確認する | 本番でtrueになっていないか確認する |
| 5 | useMonitorを確認する | 1分未満の高頻度ジョブで意図した設定か確認する |
| 6 | Storageと権限を確認する | AzureWebJobsStorage、RBAC、マネージドIDを確認する |
| 7 | タイムゾーンを確認する | UTC換算か、対応プランでWEBSITE_TIME_ZONEを使うか決める |
| 8 | C#実行モデルを確認する | in-processなら移行計画を作る |
| 9 | ステージングでテストする | Log streamやApplication Insightsで予定どおり実行されるか見る |
| 10 | 失敗時の再実行設計を確認する | Timer trigger単体に自動リトライを期待していないか確認する |

このチェックリストで重要なのは、スケジュール式だけを見ないことです。Timer triggerの障害は、CRON式の誤りだけでなく、Storage権限、ホストID、タイムゾーン、デプロイ時の起動、処理時間超過でも発生します。

よくある失敗と対策

日本時間のつもりでUTCの時刻を書いている

Azure FunctionsのTimer triggerでは、CRON式の既定タイムゾーンはUTCです。日本時間の午前9時に実行したい処理を0 0 9 * * *と書くと、UTC 9:00、つまり日本時間18:00に動きます。

日本時間9:00にしたいなら、UTC換算では次のようになります。

0 0 0 * * *

タイムゾーン設定を使える環境ではWEBSITE_TIME_ZONEも選択肢になりますが、LinuxのFlex Consumption/Consumptionではサポート制約があるため、プランを確認してから採用してください。

デプロイのたびに処理が走ってしまう

runOnStartuptrueになっていると、Function Appの起動時に関数が実行されます。開発中は便利ですが、本番ではデプロイ、再起動、スケールアウトのタイミングで想定外の処理が起きる可能性があります。

本番では原則として次の考え方にしてください。

runOnStartup = false

初回デプロイ直後に一度だけ実行したい場合は、Timer triggerの通常スケジュールに任せるのではなく、手動実行、専用の初期化処理、または管理されたデプロイ手順に分けるほうが安全です。

失敗したジョブがすぐ再実行されると思っている

Timer triggerは、関数が失敗してもすぐには再試行されません。次のスケジュール時刻まで呼び出されないため、業務上の再試行が必要な処理では設計を分ける必要があります。

たとえば、次のような設計が現実的です。

  • Timer triggerは「定期的に起動するだけ」の役割にする
  • 実処理はQueueやService Busにメッセージとして投入する
  • リトライ、デッドレター、失敗通知は下流の処理で管理する
  • 重要な処理はApplication Insightsで失敗を検知する

このように分離すると、Timer triggerのスケジュール制御と、業務処理の再試行制御を混同せずに済みます。

同じStorageを複数Function Appで共有している

複数のFunction Appで同じStorageアカウントを使う構成は、コストや管理の都合で採用されることがあります。しかしTimer triggerでは、ストレージロックとホストIDが関係するため、同じ識別構成を共有すると期待どおりに動かない可能性があります。

複数Function AppでStorageを共有する場合は、AzureFunctionsWebHost__hostidを明示的に分けることを検討してください。特に、環境複製やスロット、検証環境を本番と似た名前で作る場合は、ホストIDの重複に注意が必要です。

これから取るべき行動

Timer trigger for Azure Functionsの今回の確認ポイントは、仕様変更への緊急対応というより、運用品質を上げるための棚卸しです。まずは本番環境のTimer triggerを一覧化し、schedulerunOnStartupuseMonitorAzureWebJobsStorage、タイムゾーン、C#実行モデルを確認してください。

新規構築では、スケジュールをアプリ設定に外出しし、ローカルではAzuriteとFunctions Core Toolsで確認し、Azureへの展開ではazdやテンプレートを使った再現性のある構成を検討します。既存のC# in-processアプリは、2026年11月10日のサポート終了を見据えて、Timer trigger単体ではなくFunction App全体の移行計画として進めるのが現実的です。

Timer triggerはシンプルな機能ですが、時刻、ストレージ、スケール、再試行、デプロイの影響を受けます。設定を一つずつ確認すれば、定期実行ジョブを安定して運用しやすくなります。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次