Azure Web AppからAzure SQL Database接続が突然失敗する時の原因と解決策|プライベートエンドポイントとVNet統合の徹底トラブルシューティング

昨日まで普通に動いていた Azure Web アプリが、朝になったら Azure SQL Database にだけ繋がらない――。そんな「突然のタイムアウト」は、原因が複数の層(DNS、ルーティング、NSG、Private Endpoint、アプリ設定)に跨るため、勘に頼ると時間を浪費しがちです。本記事では、実運用で最も起きやすい構成を前提に、最短復旧と恒久対策を両立する実践的トラブルシューティングを、コマンド例・確認画面・判定基準まで踏み込んで解説します。

目次

想定アーキテクチャと前提

本記事は次の構成を前提にしています。いずれも同一サブスクリプションのランディングゾーンにデプロイされ、管理グループレベルで「パブリック ネットワーク アクセス」を無効化しています。

  • Azure Web App(App Service):VNet 統合済み(リージョナル VNet 統合)
  • Azure SQL Server / Azure SQL Database:Private Endpoint 経由でアクセス
  • Key Vault:接続文字列やシークレットの格納(@Microsoft.KeyVault 参照やマネージド ID を想定)
  • NSG:Web App の統合サブネットおよび Private Endpoint NIC に対して適用
コンポーネント配置 / 役割今回のポイント
Web AppVNet 統合サブネットからアウトバウンドDNS サーバの解決先 / ルートが変わると突然失敗する
Azure SQLPrivate Endpoint によるプライベート到達FQDN が Private DNS ゾーンでプライベート IP に名前解決されていること
Private DNSprivatelink.database.windows.net ゾーンVNet リンクの喪失 / A レコードの破損で名前解決だけ成功しない・逆もあり得る
NSG統合サブネット / Private Endpoint NIC優先度の高い Deny に飲み込まれやすい。TCP/1433 の許可を明示

症状の特徴と誤解しやすいポイント

  • Web App → SQL だけがタイムアウトし SqlException (0x80131904) を記録。アプリはリトライの末に 500/502 を返す。
  • 一方で SSMS や Azure Portal の Query Editor では接続可能。これは 到達経路や使用 DNS が異なる ため再現しないことがある。
  • nslookup <server>.database.windows.net はプライベート IP を返すが、実通信が届かないケースがある(DNS は正常 / ルーティングや NSG が異常)。
  • NSG で Outbound 1433 を「Any → Any」で許可していても、Private Endpoint 側の NIC(受信)が遮断されていれば同様に失敗する。

最短復旧のクイックフィックス(ダウンタイム短縮)

まずは App Service のルーティングと DNS を「良い状態」に固定して復旧し、続いて恒久原因の切り分けに移るのが現場で最も速い進め方です。

App Service のトラフィック制御を強制する

Azure Portal → 対象 Web App → 設定 > 構成 > アプリ設定 に以下を追加し、保存後に Web App を再起動します。

キー値目的 / 効果
WEBSITE_VNET_ROUTE_ALL1全アウトバウンドを VNet 統合経由にルーティング。UDR の影響も受けるため、Private Endpoint へ確実に向けられる。
WEBSITE_DNS_SERVER168.63.129.16Azure 内部 DNS を明示的に使用し、Private DNS の A レコードを確実に解決する。
WEBSITE_DNS_ALT_SERVER
(任意)
(環境の予備 DNS)プライマリ障害時のフェールバック。不要なら省略可。

この 2 設定は「突然つながらない」を最短で解消する定石です。以降は根本原因を特定し、設定を残す/見直すを判断します。

恒久対策のための標準診断フロー

1. Kudu から DNS とポート疎通を実地確認

  1. Web App → 開発ツール > Advanced Tools (Kudu) を開く。
  2. コンソールで名前解決を確認。
nslookup &lt;sql-server-name&gt;.database.windows.net

期待値:Private Endpoint のプライベート IP を返します。

次に TCP 1433 の疎通確認を行います。

  • Linux コンテナ:
curl -v telnet://&lt;sql-server-name&gt;.database.windows.net:1433
# あるいは
nc -vz &lt;sql-server-name&gt;.database.windows.net 1433
# あるいは(bash 内蔵)
timeout 5 bash -c 'cat &lt; /dev/null &gt; /dev/tcp/&lt;sql-server-name&gt;.database.windows.net/1433'
  • Windows コンテナ:
tcpping.exe &lt;sql-server-name&gt;.database.windows.net 1433

ここで失敗する場合は、DNS またはルーティング(あるいは NSG)が疑わしいため、次のステップに進みます。成功する場合は、アプリコード/接続文字列/認証の問題の可能性が高まります。

2. App Service 側の DNS / ルートを強制(再掲)

前章のクイックフィックスを既に適用しても Kudu の疎通に失敗する場合、次を併せて確認します。

  • VNet 統合サブネットに UDR(0.0.0.0/0 など)がある場合、経路が誤って NVA / FW へ迂回していないか。
  • Private DNS ゾーンに A レコードが存在し、VNet リンクが有効か。

3. VNet 統合の状態を再確認

  • Web App → ネットワーク > VNet 統合 で、意図したサブネットに 接続済み になっていること。
  • 状態が 不明、切断、警告 の場合は、一度切断→同一サブネットに再統合→Web App 再起動。
  • Kudu で以下を実行し、プライベート IP が割り当てられていることを確認。
# Linux
echo $WEBSITE_PRIVATE_IP

# Windows

SET WEBSITE_PRIVATE_IP 

VNet 統合は App Service プラン変更、スケール操作、サブネット更新(委任/UDR/NSG の切替え)を契機に「静かに」不整合になることがあります。障害時はここを最初に疑うと切り分けが加速します。

4. SQL 側(Private Endpoint NIC)とサブネット NSG の受信ルール

  1. Azure SQL Server → ネットワーク > プライベート エンドポイント → 対象 PE → NIC → 効果的なセキュリティ ルール を確認。
  2. 受信 TCP/1433 が Web App の統合サブネット から許可されていること。
  3. 不足している場合は NSG に明示ルールを追加。
優先度方向ソース宛先ポートプロトコルアクション補足
< 1000受信Web App 統合サブネット CIDRSQL Private Endpoint のプライベート IP(またはサブネット)1433TCPAllow上位 Deny に飲み込まれない位置に配置

Private Endpoint では NIC 単位で NSG を評価します。ネットワーク ポリシーの状態(有効/無効)や適用先に注意してください。

5. 接続文字列の最終確認(FQDN と暗号化)

  • 必ず FQDN を使用(例:Server=tcp:<server>.database.windows.net,1433;)。Private Endpoint の IP を直書きしない。
  • 証明書エラーが出る場合は TrustServerCertificate=False を明示(True は推奨しません)。
  • Azure AD 認証(Managed Identity など)を使う場合は、タイムアウトではなく認証失敗のメッセージになるのが通常。タイムアウトはネットワーク層を優先的に疑うのがコツです。

ADO.NET(.NET)の例

Server=tcp:&lt;server&gt;.database.windows.net,1433;
Database=&lt;db&gt;;
Encrypt=True;
TrustServerCertificate=False;
Connection Timeout=30;

Managed Identity(ADO.NET)の例

Server=tcp:&lt;server&gt;.database.windows.net,1433;
Database=&lt;db&gt;;
Authentication=Active Directory Managed Identity;
Encrypt=True;
TrustServerCertificate=False;

JDBC の例

jdbc:sqlserver://&lt;server&gt;.database.windows.net:1433;
database=&lt;db&gt;;
encrypt=true;
trustServerCertificate=false;

6. 自動診断ツールの活用

Web App → 診断と解決 → ネットワーク を実行すると、DNS、VNet、SQL への疎通が自動診断され、想定不具合と推奨修復案が表示されます。運用引継ぎドキュメントには、この導線とスクリーンショットを必ず残しておくと復旧時間が短縮します。

「突然つながらない」の主要因と対処パターン

VNet 統合の不整合(スケールや構成変更の副作用)

現場頻度 No.1。App Service プランやサブネット属性(委任、UDR、NSG)の変更後、統合状態が 論理的に存在するが機能していない ことがあります。症状は「Kudu で nslookup は正しいが 1433 が開かない」もしくは「Private IP を解決できない」いずれか。

  • 対処:VNet 統合をいったん切断 → 同一サブネットへ再統合 → アプリ再起動。WEBSITE_PRIVATE_IP の再割当てを確認。
  • 再発防止:IaC(Bicep/Terraform)で VNet 関連を変更するジョブとアプリのデプロイ ジョブを分離し、順序と待機を厳格化。変更後のヘルスチェックをパイプラインに組み込みます。

Private DNS ゾーンの破損またはリンク逸脱

プライベート エンドポイントの再作成・再デプロイで A レコードが重複/欠落したり、VNet リンクが外れて別 VNet を向くことがあります。結果、SSMS や Query Editor は繋がるのに、Web App だけ解決先が別になり到達不可になります。

  • 対処:privatelink.database.windows.net ゾーンで対象サーバの A レコードを点検。Kudu で nslookup を DNS サーバ指定でも実施して結果を突き合わせます。
# Kudu(Linux)の例:Azure 内部 DNS を明示
nslookup &lt;server&gt;.database.windows.net 168.63.129.16

UDR / NVA による迂回(ブラックホール)

WEBSITE_VNET_ROUTE_ALL=1 の環境で、VNet 統合サブネットに 0.0.0.0/0 の既定ルートが NVA/FW に向いていると、NVA 障害時に SQL へのトラフィックがブラックホール化します。

  • 対処:SQL の Private Endpoint(特定の /32)宛てトラフィックは 仮想ネットワーク 宛てに戻す UDR を優先度高で追加するか、NVA で同宛先を通すポリシーを明示します。
  • 見分け方:Network Watcher の「有効なルート」で対象宛先の最終ルートが NVA になっていないか確認。

NSG の優先度競合(上位 Deny)

運用中にセキュリティ強化の Deny ルールを追加し、意図せず Private Endpoint NIC の 1433 まで塞いでしまう事故は珍しくありません。特に *Any → Any* の広い Deny は要注意。

  • 対処:Private Endpoint NIC の「効果的なセキュリティ ルール」で最終評価を確認。Allow(1433/TCP、ソースは Web App サブネット CIDR)が上位に来るように調整。

Key Vault・認証設定に起因するように見えるが実はネットワーク

ログに Key Vault 取得エラー(HTTP 408/504)が出ると認証や権限を疑いがちですが、ネットワーク層のタイムアウトが連鎖的に表面化していることが多いです。まず SQL へのポート疎通を Kudu で確認し、ネットワークが正常なら初めて認証・権限を精査します。

運用に組み込む再発防止ベストプラクティス

  • 設定の標準化:App Service の既定で WEBSITE_VNET_ROUTE_ALL=1 と WEBSITE_DNS_SERVER=168.63.129.16 を適用。例外が必要なアプリだけに Override を許可。
  • 変更管理:VNet / NSG / Private DNS / UDR を変更する IaC パイプラインには、Kudu 疎通テストの自動ジョブ(nslookup と 1433 の nc)を後続ステージとして必ず実行。
  • 監視:アプリ側は接続プールのエラー率、タイムアウト数、依存関係(SQL)の応答時間をメトリック化。SQL 側は接続失敗のカウントをログ収集。閾値超過でアラート。
  • ロールバック計画:ネットワーク変更前に、Private DNS ゾーン エクスポートと NSG ルールのバックアップ(IaC 化)を取得し、即時復旧の手順を Runbook に明記。

現場でそのまま使えるコマンド集

Kudu(Linux)

# 名前解決(既定の DNS)
nslookup <server>.database.windows.net

# 名前解決(Azure 内部 DNS を明示)

nslookup .database.windows.net 168.63.129.16

# TCP/1433 疎通

nc -vz .database.windows.net 1433 || echo "NG"

# HTTP 経由の telnet(curl)

curl -v telnet://.database.windows.net:1433

# 環境変数で VNet 統合の私設 IP を確認

echo $WEBSITE_PRIVATE_IP 

Kudu(Windows)

tcpping.exe &lt;server&gt;.database.windows.net 1433
SET WEBSITE_PRIVATE_IP

アプリ内(.NET)での診断ログ強化

// Microsoft.Data.SqlClient の詳細ログ(起動時に一時有効化)
AppContext.SetSwitch("Microsoft.Data.SqlClient.EventSource.Tracing", true);
AppContext.SetSwitch("Microsoft.Data.SqlClient.EventSource.TraceWarning", true);
AppContext.SetSwitch("Microsoft.Data.SqlClient.EventSource.TraceError", true);

復旧の意思決定を早める判定表

観点確認方法 / コマンド期待結果外れた場合の主犯候補次のアクション
DNSnslookup <server>.database.windows.net 168.63.129.16Private IP を返すPrivate DNS A レコード / VNet リンクゾーンとリンクを修正
ポート疎通nc -vz ... 1433 / tcpping ... 1433接続成功NSG、UDR、NVA/FW、VNet 統合不整合NSG の Allow を上位化、UDR を是正、統合を再作成
統合状態VNet 統合画面 / WEBSITE_PRIVATE_IP接続済 / IP あり統合破損切断→再統合→再起動
ルーティングNetwork Watcher 有効ルート宛先 PE は仮想ネットワーク宛0.0.0.0/0 の NVA 迂回PE 宛 /32 の明示 UDR 追加
接続文字列FQDN / 暗号化設定FQDN + Encrypt=True + TSC=FalseIP 直書き / 暗号化不備FQDN に戻し、証明書エラーは TSC=False で解消

NSG ルール設計のサンプル(最小権限)

Private Endpoint の受信は 必要なソースだけ を明示許可します。広い Any 許可は避け、優先度の高い位置でピンポイントに通すのがコツです。

優先度方向ソース宛先ポートアクション備考
200受信WebApp-Subnet CIDRSQL-PE NICTCP/1433Allow上位に配置
65000受信AnyAnyAnyDeny既定の終端 Deny(変更不要)

よくある質問(FAQ)

Q. SSMS は繋がるのに Web App だけ失敗します。なぜ?
A. クライアント(SSMS)が別ネットワーク/別 DNS 経路を使っているためです。Web App は統合サブネットから Private Endpoint へ、SSMS は社内 VPN や別 VNet から…といった差で再現しません。アプリの疎通は必ず Kudu で確認してください。

Q. 1433 だけ開ければ十分ですか?
A. Private Endpoint 経由の Azure SQL では、基本的に 1433/TCP の到達で足ります(Redirect モードの複数ポート解放は不要)。ただし NSG の上位 Deny で塞がないように注意してください。

Q. IP 直書きはダメ?
A. 非推奨です。Private Endpoint の再作成や障害対応で IP が変わることがあり、証明書検証の失敗(ホスト名不一致)も誘発します。FQDN を使い、DNS で解決させるのが正道です。

Q. 一時的に TrustServerCertificate=True にすると直りますか?
A. ネットワーク タイムアウトの解消には無関係です。証明書エラーの抑制には効きますが、セキュリティ上の理由から恒久設定としては推奨しません。

Q. Key Vault のエラーが出ています。先に権限を見直すべき?
A. まずはネットワーク疎通(DNS / 1433)を優先して切り分けてください。ネットワーク異常時は Key Vault 取得や他の外部依存も連鎖的にタイムアウトします。

実践ワークフロー(テンプレ)

  1. Kudu で nslookup と 1433 の疎通(失敗ならネットワーク層へ、成功ならアプリ層へ)。
  2. App 設定でルート/DNS を強制(WEBSITE_VNET_ROUTE_ALL=1、WEBSITE_DNS_SERVER=168.63.129.16)。
  3. VNet 統合を再アタッチ(切断→再統合→再起動、WEBSITE_PRIVATE_IP を確認)。
  4. Private DNS ゾーンと VNet リンク(A レコードとリンクの健全性)。
  5. NSG の効果的ルール(PE NIC 受信 1433 Allow が上位にあるか)。
  6. UDR/有効ルート(PE 宛トラフィックが仮想ネットワークへ行くか)。
  7. 接続文字列(FQDN / Encrypt=True / TSC=False)。
  8. 診断と解決(ネットワーク診断の自動チェック)。

まとめ

「昨日まで動いていたのに突然つながらない」多くの原因は、VNet 統合・DNS・NSG・UDR のいずれかの”微細なズレ”です。復旧を最速化するには、Kudu での DNS/1433 テスト → App 設定でのルート/DNS 強制 → VNet/NSG/Private DNS/UDR の順で切り分けるのが最短経路です。最後に接続文字列を FQDN + 暗号化既定に正しておけば、Private Endpoint 再作成などの将来変更にも耐性が増します。ここまでの手順(本記事 1→6)を上から順に実施すれば、大半の “突然つながらない” 事象は現場で収束できます。


付録:チェックリスト(コピペ運用用)

チェックはい / いいえ対応
Kudu で Private IP を解決できる□ / □できなければ Private DNS / VNet リンクを修正
Kudu で 1433/TCP が開通する□ / □できなければ NSG / UDR / VNet 統合を点検
App 設定でルート/DNS を強制済み□ / □WEBSITE_VNET_ROUTE_ALL=1、WEBSITE_DNS_SERVER=168.63.129.16
VNet 統合は「接続済み」□ / □切断→再統合→再起動
PE NIC 受信 1433 Allow が有効□ / □ソース=WebApp サブネット CIDR、優先度は Deny より上
接続文字列は FQDN + Encrypt=True□ / □IP 直書きを排除、TSC=False 推奨

ケーススタディ(再現しやすい落とし穴)

ケース A:Terraform の再適用で Private DNS のリンクが消失

症状:nslookup はパブリック IP を返し、アプリはタイムアウト。SSMS は Bastion 経由で接続できる。
対応:Private DNS の VNet リンクを再作成。App 設定で WEBSITE_DNS_SERVER を強制し、Kudu で再確認。

ケース B:NVA メンテ中の経路逸脱

症状:一部時間帯のみ断続的にタイムアウト。
対応:UDR の優先度を調整し、SQL PE 宛 /32 を「仮想ネットワーク」へ直行。NVA 経路に載せない設計に変更。

ケース C:セキュリティ強化で NSG Deny を上位追加

症状:Query Editor は接続できるがアプリのみ全面不可。
対応:PE NIC の効果的ルールで 1433 Allow が Deny の下に落ちていることを確認。優先度を繰り上げて解消。


推奨の運用テンプレ(Runbook 抜粋)

1) 影響確認
   - アプリのエラーレート/タイムアウト急増を検知 → 当該スロット/実働インスタンスを特定
2) 迅速復旧
   - App 設定: WEBSITE_VNET_ROUTE_ALL=1, WEBSITE_DNS_SERVER=168.63.129.16
   - 再起動 → Kudu で nslookup / 1433 疎通 OK まで確認
3) 根本原因
   - VNet 統合(接続状態 / WEBSITE_PRIVATE_IP)
   - Private DNS(A レコード / VNet リンク)
   - NSG(PE NIC の受信 1433 Allow)
   - UDR(PE 宛 /32 は仮想ネットワークへ)
4) クロージング
   - IaC に反映、変更リリース基準に「Kudu 疎通」ゲートを追加

最後に

App Service × Azure SQL × Private Endpoint は強力ですが、DNS・ルート・ポリシーのわずかな不整合が「突然のタイムアウト」を引き起こします。本記事の手順をチームの標準 Runbook に組み込み、変更のたびに自動で Kudu 疎通を走らせるだけで、復旧時間を桁違いに短縮できます。ぜひ明日からの運用に取り入れてください。

この記事を書いた人

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

コメント

コメントする

目次