2026年5月20日時点の公式情報を前提に見ると、Timer trigger for Azure Functions(Azure Functionsのタイマートリガー)は、スケジュールに沿って関数を実行するためのトリガーです。今回まず押さえるべき結論は、既存のTimer triggerの書き方を一斉に変更するような破壊的変更ではなく、公式リファレンスから実践的なクイックスタートへの導線が強化され、運用時に見落としやすい設定確認の重要度が増したことです。MicrosoftDocsの履歴では、Timer triggerの記事にエンドツーエンド例へのリンクを追加する差分が確認できます。(Microsoft Learn)
特に確認すべきなのは、schedule、runOnStartup、useMonitor、AzureWebJobsStorage、タイムゾーン、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などを含む構成例が参照しやすくなった | 新規案件ではテンプレートベースの構築を検討しやすい |
| 運用設定 | runOnStartup、useMonitor、ストレージ依存、タイムゾーン制約の確認が重要 | 設定ミスによる予期しない実行、未実行、重複停止を防ぐ必要がある |
| 移行観点 | 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つです。どれも小さな設定に見えますが、本番環境では「予定時刻に動かない」「デプロイ時に想定外に動く」「スケールアウト時に片方しか動かない」といったトラブルにつながります。
| 設定・項目 | 確認する内容 | 実務上の判断基準 |
|---|---|---|
schedule | NCRONTAB式または一部条件でTimeSpanを指定しているか | 本番ではハードコードよりアプリ設定参照を優先する |
runOnStartup | 起動時に即実行するか | 本番環境では原則false |
useMonitor | スケジュール監視を有効にするか | 1分以上の間隔なら既定でtrueだが、重要ジョブでは明示設定を検討 |
AzureWebJobsStorage | ホストストレージが正しく設定されているか | スケールアウト調整に関わるため、接続・権限を必ず確認 |
| タイムゾーン | UTC基準か、WEBSITE_TIME_ZONEを使うか | LinuxのFlex Consumption/Consumptionでは制約に注意 |
| 実行モデル | C# in-processか isolated workerか | C#は将来のサポート期限を見て移行計画を立てる |
公式リファレンスでは、schedule、runOnStartup、useMonitorが主要な設定として説明されています。また、TimeSpanはApp Serviceプランで実行するFunction Appに限って使える点も明記されています。(Microsoft Learn)
scheduleはアプリ設定に外出しする
スケジュールをコードに直接書くと、実行時刻を変更するたびに再デプロイが必要になります。実務では、次のようにアプリ設定を参照する形にしておくと運用しやすくなります。
[TimerTrigger("%TIMER_SCHEDULE%")]
アプリ設定側には、たとえば次のような値を入れます。
0 */5 * * * *
この方法なら、開発環境では30秒ごと、本番環境では5分ごと、検証環境では1時間ごと、というように環境別にスケジュールを変えられます。公式クイックスタートでも、TIMER_SCHEDULEをlocal.settings.jsonのValuesに設定する例が示されています。(Microsoft Learn)
runOnStartupは本番で安易に有効化しない
runOnStartupをtrueにすると、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_ZONEやTZが現在サポートされていないと説明されています。この条件に当てはまる場合は、タイムゾーン設定に頼らず、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)
管理者が確認すべきポイントは次のとおりです。
| 確認項目 | 見る場所 | 判断基準 |
|---|---|---|
AzureWebJobsStorage | Function Appの構成、アプリ設定 | 接続文字列またはIDベース接続が正しく設定されている |
| マネージドID | Function AppのID設定 | 有効化され、対象Storageへアクセスできる |
| RBAC | Storageアカウントのアクセス制御 | 必要なロールが付与されている |
| 共有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が有効な例があっても、本番では無条件に流用しないでください。公式クイックスタートでも、本番では予期しない実行を避けるためにrunOnStartupをfalseにする旨が示されています。(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ではサポート制約があるため、プランを確認してから採用してください。
デプロイのたびに処理が走ってしまう
runOnStartupがtrueになっていると、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を一覧化し、schedule、runOnStartup、useMonitor、AzureWebJobsStorage、タイムゾーン、C#実行モデルを確認してください。
新規構築では、スケジュールをアプリ設定に外出しし、ローカルではAzuriteとFunctions Core Toolsで確認し、Azureへの展開ではazdやテンプレートを使った再現性のある構成を検討します。既存のC# in-processアプリは、2026年11月10日のサポート終了を見据えて、Timer trigger単体ではなくFunction App全体の移行計画として進めるのが現実的です。
Timer triggerはシンプルな機能ですが、時刻、ストレージ、スケール、再試行、デプロイの影響を受けます。設定を一つずつ確認すれば、定期実行ジョブを安定して運用しやすくなります。

コメント