Azure Functions(Flex Consumption)を複数サブスクリプション/リージョンへ同一コードでデプロイしたのに、特定の古い Function App だけ HTTP トリガーが検出されず失敗する…。本記事では「ポータルに warm up しか出ない」症状を中心に、原因の見立てと、再起動・トリガー再同期・新規アプリへ移行まで、現場で効く対処手順を具体的にまとめます。
現象の整理:サブスクリプション/リージョンで挙動が揺れるときに見るべき視点
同じリポジトリ、同じ環境変数、同じアプリ設定であっても、Azure Functions の「トリガー検出」は「デプロイが完了した瞬間」に必ず揃うとは限りません。特に Flex Consumption のようにスケールや初期化が自動化されているプランでは、デプロイ処理・ホスト起動・トリガー同期のタイミングがずれると、ポータル上では一時的に関数が見えない状態になります。
ただし今回のポイントは、単なる一時的な遅延ではなく「古い Function App だけが恒久的に失敗する」点です。まずは状況を表に落として、切り分けの前提を揃えましょう。
| デプロイ先 | デプロイ結果 | ポータルの表示 | 実害 | 切り分けの示唆 |
|---|---|---|---|---|
| サブスクリプションA(米国リージョン) | 毎回失敗 | HTTP トリガーが検出されない/関数が出てこない | サービス利用不可 | 単なる遅延ではなく、ホスト側の状態不整合やメタデータ破損の可能性 |
| サブスクリプションB(米国・東南アジア・日本) | 一見すると検出されないことがあるが完了後は成功 | デプロイ完了後にトリガーが表示 | 最終的に正常 | トリガー同期が遅れているだけのケースに近い |
| 同一リージョンで新規作成した Function App | 成功 | HTTP トリガーが表示 | 正常 | リージョンや設定差ではなく、特定アプリ個体の問題が濃厚 |
| 元から存在する古い Function App | 失敗が継続 | ポータルには warm up のみ/HTTP トリガーが出ない | 正常提供できない | アプリ内部メタデータの不整合、過去のデプロイ履歴による壊れ状態の疑い |
結論:原因は「コード」より「Function App 側のトリガー情報(内部メタデータ)の不整合」が疑わしい
今回のように新規作成した Function App では同じ構成が動くのに、古い Function App だけが同じデプロイで失敗する場合、原因の中心は「サブスクリプション差」「リージョン差」よりも、その Function App の内部状態(メタデータやキャッシュ)が壊れている/更新されないことに寄っているケースが多いです。
Azure Functions では、コードの中にあるトリガー定義(HTTP トリガーなど)と、Azure 側が管理する「このアプリにはどのトリガーがあるか」という管理用メタデータが別レイヤーで扱われます。デプロイ自体は成功してコードが置けていても、次のどこかでつまずくとポータルに関数が出ない状態になります。
| レイヤー | 何が行われるか | ここが壊れると起きること | 観測できる代表的なサイン |
|---|---|---|---|
| デプロイ(成果物配置) | パッケージが Function App のファイル領域に配置される | 配置失敗、または古い成果物が残る | デプロイログにエラー/想定外のファイル構成 |
| ホスト起動(Functions ホスト) | ホストが起動して関数をインデックス(検出)する | 起動できず、関数の検出が進まない | ログに起動失敗/例外/「関数が見つからない」系メッセージ |
| トリガー同期(メタデータ更新) | 検出結果が Azure 側へ同期され、ポータルや管理 API が参照できる | ポータルに関数が出ない、warm up だけになる | ターミナル上では見えるのにポータルは空/同期コマンドで改善 |
「ターミナル(デプロイログ)ではトリガーが見えるのに、サーバー側(ポータル)には warm up しか存在しない」という情報は、まさにトリガー同期レイヤーの不整合を強く示唆します。
まず確認すべきチェックリスト:設定が同じでも“実体”が違うポイント
「同一設定」と言っても、Function App は長く運用すると過去の変更履歴や内部的な移行の影響を受けます。対処に入る前に、少なくとも次の項目が一致しているかを確認しておくと、無駄な試行錯誤を減らせます。
| 確認項目 | どこで見る | 期待値 | ズレていた場合の影響 |
|---|---|---|---|
| ランタイム設定(言語/ワーカー) | アプリ設定(例:FUNCTIONS_WORKER_RUNTIME) | 全環境で同一 | 関数の読み込み方式が変わり、トリガー検出に失敗しやすい |
| Functions 拡張バージョン | アプリ設定(例:FUNCTIONS_EXTENSION_VERSION) | 意図したバージョンで固定、または同一ポリシー | 古いアプリだけ挙動が変わる/アップグレード影響が残る |
| ストレージ接続 | アプリ設定(例:AzureWebJobsStorage) | 接続先・権限・ネットワークが到達可能 | ホストが初期化できず、トリガーが一切出ないことがある |
| デプロイ方式 | CI/CD、デプロイセンター、成果物 | Zip/Run-From-Package など同一方式 | 古いアプリだけ「増分デプロイの残骸」で壊れやすい |
| アプリが参照する構成ファイル | 成果物に含まれる host.json や関数定義 | 期待する構成が配置されている | ホストは起動しても関数が列挙されない |
| プラン種別と作成時期 | Function App のプラン表示、作成日 | Flex Consumption で統一 | 過去プランからの移行で内部状態が残り、同期不良を起こすことがある |
このチェックで「本当に完全一致」だと確認できた場合、次は状態を正しい方向に“戻す”作業(再起動・同期)に移ります。
最短で直すための対処フロー:再起動 → トリガー再同期 → 直らなければ新規作成
原因がアプリ個体の不整合に寄っている場合、深掘りよりもまず復旧を優先した方がビジネス的に正解になることが多いです。以下の順で実行すると、作業が収束しやすくなります。
| 手順 | 狙い | 成功のサイン | うまくいかない場合 |
|---|---|---|---|
| 1. Function App の再起動 | キャッシュ・一時状態のリセット | ポータルに関数が戻る/ログに通常起動が出る | 2へ進む |
| 2. トリガーの再同期(sync-functions) | Azure 側メタデータを再生成・更新 | HTTP トリガーが表示される/呼び出しが通る | 3へ進む |
| 3. “クリーン”な再デプロイ | 成果物の取り違え・残骸を排除 | デプロイ後にトリガーが安定して表示 | 4へ進む |
| 4. 新しい Function App へ移行 | 壊れた個体を切り捨てる(最短確実) | 新アプリでは再現しない | 必要なら Microsoft サポートへ(根本原因調査) |
手順1:Function App を再起動する
ポータル上の「再起動」で十分なこともあります。古い Function App が不正状態に陥っている場合、再起動でホストの再初期化が走り、トリガー検出が復活することがあります。
- Azure ポータル → 対象の Function App → 「再起動」
- 再起動後、数分程度はポータル表示が追従しないことがあります(ホスト起動待ち)
手順2:トリガーを再同期する(az functionapp sync-functions)
「デプロイログ上ではトリガーが見えているのに、ポータルに出ない」場合に特に有効なのがトリガー再同期です。これはデプロイ済みのコードからトリガー情報を再検出し、Azure 側の管理メタデータを更新する操作です。
実行前の注意
- 誤ったサブスクリプションを対象にしないよう、Azure CLI のアカウントコンテキストを確認します。
- 権限(少なくとも対象 Function App の更新権限)が必要です。
az account show
az account set --subscription <サブスクリプションIDまたは名前>
az functionapp sync-functions \
--name <FunctionApp名> \
--resource-group <リソースグループ名>
実行後は、ポータルの Functions 一覧を更新(リロード)し、HTTP トリガーが表示されるかを確認します。表示が戻ったら、実際にエンドポイントへアクセスして 200 応答が返るかまで確認すると安心です。
手順3:同じやり方でもう一度“クリーン”にデプロイする
sync-functions で改善しない場合でも、成果物の取り違え・残骸が原因なら再デプロイで復活することがあります。重要なのは「同じパイプラインで再実行」ではなく、成果物が正しいことを担保した上でやり直すことです。
- ビルド成果物に、HTTP トリガーを含む関数定義が確実に入っているかを確認
- デプロイの中断・並列実行が起きていないか(同時デプロイは壊れ状態を作りやすい)
- 可能なら「run from package」など、ファイルが不整合を起こしにくい方式に寄せる
手順4:改善しない場合は新しい Function App に移行する(最短確実)
再起動や sync-functions を複数回試しても改善しないときは、問題の Function App が復旧困難な状態に陥っている可能性があります。この場合、深追いよりも新規 Function App を作り直して移行するのが、最も速く確実です。
実際に同じリージョン・同じ設定で新規作成した Function App が正常に動作しているなら、移行は成功パターンです。移行時は次のチェックリストを使うと抜け漏れが減ります。
| 移行対象 | 具体例 | 落とし穴 | おすすめ |
|---|---|---|---|
| アプリ設定(環境変数) | 接続文字列、API キー、フラグ設定 | スロット設定の有無、Key Vault 参照の違い | エクスポートして差分比較してから投入 |
| マネージド ID / 権限 | Key Vault、Storage、Cosmos DB など | 古いアプリだけ権限が残っている/新アプリに付与し忘れ | 最初に必要最小権限で付け直す |
| ネットワーク設定 | VNet 統合、アクセス制限、Private Endpoint | 新アプリは既定で外部疎通不可になるケース | 疎通要件を表にして一つずつ反映 |
| 監視 | Application Insights、ログ設定 | 正常時に気づけず、再発してから発見 | 起動失敗と同期失敗を検知するアラートを用意 |
| ドメイン/DNS/フロント | API Management、Front Door、カスタムドメイン | 切り替え時のダウンタイム | 段階的にルーティングを切り替える |
「ポータルに warm up しか出ない」状態をもう少し具体的に理解する
ポータルに warm up しか表示されない場合、ユーザーコードの関数一覧が正しく登録されていない可能性が高いです。多くの現場では、この状態を次のように捉えると切り分けが進みます。
- コードは置けている(デプロイログに関数が出る)
- しかしAzure 側が参照する「関数一覧」が更新されていない(ポータルが空)
- 結果として、管理面では「最小限のエンドポイント(warm up 相当)」だけが見えてしまう
つまり、問題は「HTTP トリガーのコードが存在しない」ではなく、HTTP トリガーが“登録されていない”ことに近い、という整理です。この前提に立つと、sync-functions が効く理由も説明できます。
原因を深掘りするなら:古い Function App が壊れ状態になる典型パターン
移行で解決しても「なぜ起きたのか」を把握しておくと、次に同様の障害が起きたときに早く収束できます。古い Function App にだけ起きやすい典型パターンを挙げます(複数が重なることもあります)。
| 典型パターン | 起こりやすい状況 | 症状 | 対処の方向性 |
|---|---|---|---|
| 中断されたデプロイが残骸を残す | 並列デプロイ、タイムアウト、手動での停止 | ファイル構成が崩れ、検出が不安定 | クリーン再デプロイ/run from package 化 |
| ランタイムや拡張の移行影響が残る | 長期運用でアップグレードを繰り返した | 新規アプリでは再現しない | アプリ作り直しで状態をリセット |
| トリガー同期メタデータが破損・停滞 | デプロイは通るが同期が失敗する | ポータルに関数が出ない/warm up のみ | sync-functions/再起動/作り直し |
| 依存リソース到達性の変化 | ストレージのネットワーク制限、権限変更 | ホストが起動できず、関数が列挙されない | 到達性と権限の再確認、監視強化 |
再発防止:Flex Consumption で“壊れにくい”デプロイと運用のコツ
Flex Consumption は運用負荷を減らせる一方で、プラットフォームの自動化領域が広い分、状態不整合が起きたときに「なぜ?」が見えにくい面があります。次の工夫で再発率を下げられます。
- インフラをコード化(IaC)する:Bicep/Terraform などで Function App を再現可能にし、「壊れたら作り直す」が怖くない状態にする。
- デプロイは単一経路に統一:手動デプロイと CI/CD を混在させない。並列デプロイを避ける。
- 設定差分を定期的に棚卸し:古いアプリほど“見えない差分”が増えるため、アプリ設定をエクスポートして差分チェックする運用にする。
- 起動失敗を早期検知:Application Insights などでホスト起動エラー、関数列挙失敗の兆候をアラート化する。
- 「同期」も運用手順に含める:デプロイ直後に自動でトリガー同期を走らせる(運用ポリシーとして決める)と、ポータル表示と実体のズレを減らせる。
よくある質問(FAQ)
同一リージョンでも新旧で挙動が違うのはなぜ?
Function App は「作成時の既定値」「過去のアップグレード」「デプロイ履歴」などを引きずることがあり、同じ設定を入れたつもりでも内部状態が一致しないことがあります。新規作成で解消するのは、こうした“履歴”をリセットできるためです。
az functionapp sync-functions は何を壊しますか?安全ですか?
同期はコードを書き換える操作ではなく、デプロイ済みの内容からトリガー情報を再生成して Azure 側のメタデータを更新するイメージです。一般的には安全に実行できますが、業務影響を避けたい場合は、先に再起動やテスト環境で試し、実行後にエンドポイント疎通まで確認してください。
サブスクリプションAだけ失敗する場合、サブスクリプション側の制約はあり得ますか?
あり得ます。たとえば権限、ポリシー、ネットワーク制約などが異なると、デプロイや起動が失敗することがあります。ただし今回のように「同一条件で作った新規 Function App が正常」という事実がある場合、サブスクリプション差よりも古いアプリ個体の不整合に重みが寄るため、まずは再起動・同期・作り直しの順で復旧を優先するのが現実的です。
どうしても原因を確定させたい場合、何を残しておくべき?
次の情報が揃っていると、社内エスカレーションや Microsoft サポートへ相談するときに話が早くなります。
- 失敗する Function App と成功する Function App のアプリ設定差分(エクスポートして比較)
- デプロイ手順(CI/CD のジョブログ、実行日時、成果物のハッシュなど)
- 再起動・sync-functions 実行の日時と結果
- 失敗時のログ(ホスト起動、例外、関数列挙に関するメッセージ)
まずはサービス復旧を最優先に、再起動 → sync-functions → 作り直しの順で手を動かすと、今回のタイプのトラブルは短時間で収束しやすくなります。

コメント