Azure App Service を Windows から Linux に移行したいが、顧客ファイアウォールで許可済みの送信元IP(Outbound IP)を変えられない――この悩みは移行案件で頻出です。本記事では「Windows 側の送信元IPを Linux 側へ移す」ことの可否と、移行後も出口IPを固定して運用するための現実的な設計・手順を具体的にまとめます。
今回の要件を整理:何を「変えたくない」のか
前提は次のような状況です。
- 現状:Windows ベースの App Service(例:
api-appservice)がcurrent-windows-plan上で稼働している - 顧客側:あなたのアプリから顧客システムへ出ていく通信について、送信元グローバルIP(Outbound IP)を許可リストに登録済み
- やりたいこと:Linux ベースの App Service プラン(
target-linux-plan)へ移行したい - 重要条件:移行後も、顧客の許可リスト(ホワイトリスト)をできるだけ変えたくない
- 想定手順:Windows 側のアプリを削除し、同名(
api-appservice)で Linux 側に作り直して IP を引き継ぐ、という発想
ここでのポイントは、「アプリ名」や「Windows / Linux」といった表層よりも、顧客が許可しているのは“送信元IP(出口IP)”であるという点です。つまり、移行で最優先すべきは“出口を自分でコントロールできる構成”に寄せることです。
結論:Windows プランの送信元IPを Linux プランへ「移す」ことはできない
マルチテナントの Azure App Service において、Windows プランで使っていた Outbound IP を、Linux プランへそのまま移植・引き継ぎすることはできません。同じ名前で作り直しても、同じ送信元IPになる保証はありません。
理由はシンプルで、App Service の Outbound IP は「アプリ名」ではなく、App Service の配置(デプロイメントユニットやプラン配置単位)に紐づく共有IPセットとして扱われ、アプリの削除・再作成やプラン移動などで変わり得るためです。
まず押さえる:App Service の Outbound IP は「固定IP」ではない
Azure ポータルの「プロパティ」などで確認できる IP 表示は、実務上しばしば誤解されます。App Service には、少なくとも次の2種類の “Outbound IP 情報” が出てきます。
| 項目 | 意味 | 現場での使いどころ | 注意点 |
|---|---|---|---|
| Outbound IP Addresses | 「いま実際に使われる可能性がある」送信元IPのセット | 顧客の許可リストに入れてもらう候補 | ランタイムでランダムに選ばれるため、原則として表示される“全部”を許可が必要 |
| Possible/Additional Outbound IP Addresses | 将来のスケールやティア変更などで“使われ得る”送信元IPの集合 | 変更通知や将来の拡張を見越したリスク評価 | これを全部ホワイトリスト化するのは現実的でないことが多い |
さらに、Outbound IP は運用中でも変化し得ます。公式のガイダンスでも、アプリ削除・再作成や、最後のアプリを削除して再作成、プランのスケールやティア変更などで Outbound IP セットが変わる可能性が示されています。
Outbound IP が変わりやすい操作(代表例)
| 操作 | Outbound IP 変更リスク | 補足 |
|---|---|---|
| アプリを削除して作り直す | 高い | 同名で再作成しても、同じ配置単位に戻る保証はない |
| 別のプランへ移動(またはプランを作り直し) | 高い | 配置先が変われば IP セットも変わり得る |
| スケール(特にティア間の移動) | 中〜高 | ティア変更で IP セットが増減するケースがある |
なぜ「削除して同名で作り直す」では解決しないのか
想定されている手順は次の通りです。
- Windows プラン上の App Service を削除
- 同じ名前(
api-appservice)で Linux プラン上に App Service を作成
この方法が危険な理由は、大きく3つあります。
- アプリ名は IP の引き継ぎ条件ではない:アプリ名は DNS 名(
xxxx.azurewebsites.net)の一部に過ぎず、Outbound IP の割り当てとは直接結びつきません。 - 削除・再作成は Outbound IP が変わる典型トリガー:削除→再作成は、まさに Outbound IP が変わりやすい操作に該当します。
- そもそも “旧IPを新プランへ移す” という機能がない:Windows の IP セットを Linux のプランへ移植することはサポートされません。
つまり、「顧客の許可リストを変えたくない」のであれば、アプリの作り直しで運任せにするのではなく、出口IPを“自分の資産”として持つ設計へ切り替える必要があります。
王道の解決策:VNet 統合 + NAT Gateway で「固定の出口IP」を持たせる
App Service(Windows / Linux どちらでも)で出口IPを安定させる定番パターンが、regional VNet Integration(VNet 統合)+ NAT Gatewayです。
公式ドキュメントでも、VNet 統合と NAT Gateway により、アプリの送信元IPを NAT Gateway 側の固定 Public IP に制御できる旨が案内されています。
構成イメージ(ざっくり)
App Service (Windows or Linux)
└─ VNet Integration(統合サブネットへ接続)
└─ Route all(すべてのアウトバウンドをVNetへ)
└─ NAT Gateway(Public IP / IP Prefix)
└─ Internet / 顧客公開エンドポイント
この構成で何が嬉しいのか
- 顧客に許可してもらうのは App Service 由来の共有IPではなく、NAT Gateway の Public IPになる
- Windows → Linux、プラン変更、アプリ再作成をしても、出口IPは NAT 側で固定できる
- 固定IPが「運用の前提」になるので、移行後の追加変更(スケールや構成変更)でも火消しが減る
選択肢比較(どれを選ぶべき?)
| 方式 | 出口IPの固定 | 難易度 | コスト感 | 向いているケース |
|---|---|---|---|---|
| VNet 統合 + NAT Gateway | 強い(固定しやすい) | 中 | 中(NAT課金が追加) | 最短で「固定の出口IP」を作りたい/Windows→Linux移行を安全にしたい |
| Azure Firewall(SNAT) | 強い(設計次第) | 高 | 高(Firewall課金) | 監査・検査・ログ・集中管理も含めて“出口”を統制したい |
| App Service Environment(ASE) | 強い(専有環境) | 高 | 高 | 大規模・厳格要件(ネットワーク分離/専有)で App Service を使いたい |
推奨手順:既存 Windows アプリを先に NAT 配下にし、移行後も同じ出口IPを使う
ここが実務で一番大事です。“Windows の既存IPを Linux に引き継ぐ” はできませんが、次の順番にすると、顧客側の許可リスト変更を最小回数(現実的には1回)に抑えやすくなります。
全体の流れ(移行の考え方)
- まず「将来も固定にしたい出口IP」を NAT Gateway の Public IP として用意する
- 顧客に、その NAT の IP を許可リストへ追加してもらう(旧IPは残したまま)
- 既存 Windows アプリを VNet 統合 + Route all + NAT に接続し、出口IPを NAT に切り替える
- Linux アプリも同じ VNet 統合サブネットへ接続して、同じ NAT から出す
- アプリ切り替え後、不要になった Windows 側を停止・削除する
この流れなら、顧客側は「新しい固定IPを追加するだけ」で済み、いったん許可した後は OS 変更やプラン変更のたびに許可リストが揺れにくくなります。
ステップ別:作業内容と影響点
| ステップ | やること | 影響/注意 | チェックポイント |
|---|---|---|---|
| 準備 | VNet と統合用サブネットを用意 | サブネットは App Service 用に確保。サイズ設計が重要 | サブネット委任が Microsoft.Web/serverFarms |
| 準備 | NAT Gateway(Public IP / Prefix)作成 | 顧客に許可してもらう IP になる | Standard SKU / 1IP or 複数IP |
| 切替(先にWindows) | 既存 Windows アプリを VNet 統合 + Route all | ここで出口IPが NAT に切り替わる | 外部IP確認で NAT の IP が返る |
| 構築(Linux) | Linux アプリ作成→同じサブネットへ VNet 統合 | 同名で並行稼働できないことが多いので名前戦略が必要 | Linux 側も同じ NAT IP になる |
| 本番切替 | DNS / 経路 / クライアント設定を切替 | 入口の切替は別テーマ。出口IPは同じなので顧客FWは安定 | 監視・ログでエラー増加がない |
具体手順:VNet と NAT Gateway の作り方(要点だけ)
VNet と統合用サブネットの設計ポイント
- 統合用サブネットは App Service 専用にする(他用途と混在させない)
- サブネットは委任(delegation)を
Microsoft.Web/serverFarmsにする - 最小 /28(16アドレス)が要件。実務ではスケールや将来を見越して /26(64アドレス)以上を検討するのが安全
- マルチプランで同一サブネットに参加させる運用(MPSJ)を想定するなら、さらに余裕を持たせる(インスタンス数に応じてIP消費)
NAT Gateway の作成と注意点
- NAT Gateway は Standard SKU の Public IP / Public IP Prefix を使用
- 割り当てられる Public IP の合計は最大16(IP単体でも Prefix でも合算)
- 複数IPを付けた場合、アウトバウンド時の送信元IPはランダムに選ばれ得るため、顧客の許可リストは“IP全部”が必要
App Service 側:VNet 統合と Route all の有効化が必須
NAT Gateway を付けても、App Service 側で「VNet 統合」+「Route all(全トラフィックをVNetへ)」が有効でなければ、アウトバウンドが NAT を通りません。NAT 統合の手順でも Route all を有効化することが前提になっています。
設定は Azure ポータルから行えますが、環境によってはアプリ設定として WEBSITE_VNET_ROUTE_ALL を使う方法も知られています(ただし、ポータル側の Route all 設定が優先される/無視されるケースがあるため、まずはポータルでの設定状態を正として確認するのが安全です)。
確認方法:本当に NAT の固定IPから出ているかを必ず検証する
「設定したつもり」でも、Route all の見落としやサブネット紐付けミスで、出口IPが変わっていないケースがよくあります。以下の複数手段で確認しましょう。
| 確認方法 | 手順 | 期待する結果 |
|---|---|---|
| ランタイム確認(推奨) | アプリのコンソール(Kudu/SSH)で外部のIP表示サービスへ curl | NAT Gateway の Public IP が返る |
| ポータル | App Service の「プロパティ」/「ネットワーク」関連の Outbound 表示を確認 | NAT の IP がアウトバウンド候補として見える |
| CLI/PowerShell | az webapp show や Get-AzWebApp で Outbound IP を取得 | 表示上でも NAT 側のIPを追える |
CLI 例(値は環境に合わせて置換してください)。
az webapp show --resource-group <rg> --name <appname> --query outboundIpAddresses --output tsv
az webapp show --resource-group <rg> --name <appname> --query possibleOutboundIpAddresses --output tsv
PowerShell 例。
(Get-AzWebApp -ResourceGroup <rg> -Name <appname>).OutboundIpAddresses
(Get-AzWebApp -ResourceGroup <rg> -Name <appname>).PossibleOutboundIpAddresses
設計の補足:SNAT ポート枯渇と「複数IP」の考え方
顧客が許可してくれるからといって、Public IP を1つに固定すれば常に安心、とは限りません。大量の同時接続(特に同一宛先への短時間多接続)があると、SNAT ポート枯渇が起き、外向き通信が失敗することがあります。
NAT Gateway は Public IP 1つあたり 64,512 の SNAT ポートを提供し、最大 16 IP まで拡張できるため、大規模アウトバウンドでも設計しやすいのが強みです。
| 症状 | 原因の例 | 対策 |
|---|---|---|
| 特定の外部APIだけタイムアウト/接続失敗が増える | 同一宛先への同時接続が多く、SNAT ポートが枯渇 | Public IP を増やす(IP Prefix を使う)、接続の使い回し(HTTP keep-alive)、リトライ制御を見直す |
| 負荷時だけ断続的に失敗する | ピーク時の瞬間風速でポートが不足 | ピーク時の接続数を計測し、必要なら NAT 側のIP数を増やす |
重要:NAT Gateway に複数 IP を持たせる場合、送信元IPは“固定の1個”ではなく“その集合のどれか”になり得ます。顧客の許可リストは、その前提で設計・合意しておきましょう。
落とし穴:Route all を有効にしないと「App Service 既定のIP」から出てしまう
VNet 統合だけを設定した状態だと、アプリの通信のうち「プライベート宛(RFC1918)」のみ VNet に流れ、インターネット向けは従来通り App Service 既定の Outbound IP を使い続ける構成になりがちです。
Route all を有効にして初めて、アウトバウンド全体が VNet 側へ流れ、NAT Gateway で出口IPを固定できます。
落とし穴:NAT Gateway は「同一VNet内のサブネット」に紐づく
ネットワークが hub-spoke 構成の場合、「hub に NAT を置いて spoke から共通の出口IPを使いたい」という相談がよくあります。ただし NAT Gateway 自体は仮想ネットワーク/サブネットの性質に紐づくため、前提を整理せずに組むと期待通りになりません。
- NAT Gateway は複数の仮想ネットワークに同時にアタッチできません(同一VNet内のサブネットに関連付ける設計)
- hub-spoke で出口を集約したい場合、NVA(仮想アプライアンス)を介して集約し、NAT Gateway を組み合わせる設計パターンもあります
「顧客に許可してもらう IP を1つにしたい」という要件は、ネットワーク全体設計とセットで効いてきます。App Service だけ見ていると詰まるので、早めにネットワーク担当と握っておくのが安全です。
運用設計:顧客の許可リスト変更を最小化する“段階移行”のすすめ
冒頭の問いに戻ると、「Windows の送信元IPを Linux に移す」ことで許可リストを一切変えない、というのはできません。
ただし現場で実現したいのは多くの場合、次のどちらかです。
- 顧客側の変更回数を減らしたい(毎回の移行・スケールで揺れないようにしたい)
- 変更が必要でも、業務影響(ダウンタイム)を出さずに切り替えたい
そのために効くのが「許可リストを“置き換え”ではなく“追加”で始める」やり方です。タイムラインにすると次のイメージです。
| タイミング | あなた側の作業 | 顧客側の作業 | 狙い |
|---|---|---|---|
| 移行前 | NAT Gateway の Public IP を確定 | NAT の IP を許可リストに「追加」 | 切替当日の詰まりを無くす |
| 移行前(小さな作業枠) | 既存 Windows アプリを NAT 配下へ(Route all もON) | (作業済みなら不要) | 出口IPを固定化し、以降の作業の土台を作る |
| 移行本番 | Linux アプリへ切替(同じ NAT から送信) | 原則不要 | 顧客FWは“既に許可済みのNAT IP”のまま |
まとめ:Windows→Linux移行で「送信元IPを変えない」を実現する最短ルート
- App Service の Outbound IP はアプリ名に紐づかず、削除・再作成やプラン移動で変わり得るため、「IPを移す」「同名で作り直して維持」はできない
- 固定の出口IPが必要なら、VNet 統合 + Route all + NAT Gateway で、顧客に許可してもらうIPを “自分が管理できるIP” にする
- 実務では、既存 Windows アプリを先に NAT 配下へ乗せてから Linux へ移行すると、顧客側の許可リスト変更を最小化しやすい
- Route all の有効化、サブネット設計、SNAT ポート、複数IP時の許可リストなど、運用で詰まりやすい点は事前にチェックする
「顧客の許可リストを二度と揺らさない」状態を作るには、移行の一回だけでなく、移行後のスケール・構成変更も含めて出口IPを固定する設計にしておくことが最大の保険になります。App Service の Windows→Linux 移行を機に、出口を “運任せの共有IP” から “管理可能な固定IP” へ切り替えるのが正攻法です。

コメント