昨日まで普通に動いていた 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 App | VNet 統合サブネットからアウトバウンド | DNS サーバの解決先 / ルートが変わると突然失敗する |
| Azure SQL | Private Endpoint によるプライベート到達 | FQDN が Private DNS ゾーンでプライベート IP に名前解決されていること |
| Private DNS | privatelink.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_ALL | 1 | 全アウトバウンドを VNet 統合経由にルーティング。UDR の影響も受けるため、Private Endpoint へ確実に向けられる。 |
WEBSITE_DNS_SERVER | 168.63.129.16 | Azure 内部 DNS を明示的に使用し、Private DNS の A レコードを確実に解決する。 |
WEBSITE_DNS_ALT_SERVER(任意) | (環境の予備 DNS) | プライマリ障害時のフェールバック。不要なら省略可。 |
この 2 設定は「突然つながらない」を最短で解消する定石です。以降は根本原因を特定し、設定を残す/見直すを判断します。
恒久対策のための標準診断フロー
1. Kudu から DNS とポート疎通を実地確認
- Web App → 開発ツール > Advanced Tools (Kudu) を開く。
- コンソールで名前解決を確認。
nslookup <sql-server-name>.database.windows.net
期待値:Private Endpoint のプライベート IP を返します。
次に TCP 1433 の疎通確認を行います。
- Linux コンテナ:
curl -v telnet://<sql-server-name>.database.windows.net:1433
# あるいは
nc -vz <sql-server-name>.database.windows.net 1433
# あるいは(bash 内蔵)
timeout 5 bash -c 'cat < /dev/null > /dev/tcp/<sql-server-name>.database.windows.net/1433'
- Windows コンテナ:
tcpping.exe <sql-server-name>.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 の受信ルール
- Azure SQL Server → ネットワーク > プライベート エンドポイント → 対象 PE → NIC → 効果的なセキュリティ ルール を確認。
- 受信 TCP/1433 が Web App の統合サブネット から許可されていること。
- 不足している場合は NSG に明示ルールを追加。
| 優先度 | 方向 | ソース | 宛先 | ポート | プロトコル | アクション | 補足 |
|---|---|---|---|---|---|---|---|
| < 1000 | 受信 | Web App 統合サブネット CIDR | SQL Private Endpoint のプライベート IP(またはサブネット) | 1433 | TCP | Allow | 上位 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:<server>.database.windows.net,1433;
Database=<db>;
Encrypt=True;
TrustServerCertificate=False;
Connection Timeout=30;
Managed Identity(ADO.NET)の例
Server=tcp:<server>.database.windows.net,1433;
Database=<db>;
Authentication=Active Directory Managed Identity;
Encrypt=True;
TrustServerCertificate=False;
JDBC の例
jdbc:sqlserver://<server>.database.windows.net:1433;
database=<db>;
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 <server>.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 <server>.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);
復旧の意思決定を早める判定表
| 観点 | 確認方法 / コマンド | 期待結果 | 外れた場合の主犯候補 | 次のアクション |
|---|---|---|---|---|
| DNS | nslookup <server>.database.windows.net 168.63.129.16 | Private 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=False | IP 直書き / 暗号化不備 | FQDN に戻し、証明書エラーは TSC=False で解消 |
NSG ルール設計のサンプル(最小権限)
Private Endpoint の受信は 必要なソースだけ を明示許可します。広い Any 許可は避け、優先度の高い位置でピンポイントに通すのがコツです。
| 優先度 | 方向 | ソース | 宛先 | ポート | アクション | 備考 |
|---|---|---|---|---|---|---|
| 200 | 受信 | WebApp-Subnet CIDR | SQL-PE NIC | TCP/1433 | Allow | 上位に配置 |
| 65000 | 受信 | Any | Any | Any | Deny | 既定の終端 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 取得や他の外部依存も連鎖的にタイムアウトします。
実践ワークフロー(テンプレ)
- Kudu で nslookup と 1433 の疎通(失敗ならネットワーク層へ、成功ならアプリ層へ)。
- App 設定でルート/DNS を強制(
WEBSITE_VNET_ROUTE_ALL=1、WEBSITE_DNS_SERVER=168.63.129.16)。 - VNet 統合を再アタッチ(切断→再統合→再起動、
WEBSITE_PRIVATE_IPを確認)。 - Private DNS ゾーンと VNet リンク(A レコードとリンクの健全性)。
- NSG の効果的ルール(PE NIC 受信 1433 Allow が上位にあるか)。
- UDR/有効ルート(PE 宛トラフィックが仮想ネットワークへ行くか)。
- 接続文字列(FQDN / Encrypt=True / TSC=False)。
- 診断と解決(ネットワーク診断の自動チェック)。
まとめ
「昨日まで動いていたのに突然つながらない」多くの原因は、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 疎通を走らせるだけで、復旧時間を桁違いに短縮できます。ぜひ明日からの運用に取り入れてください。

コメント