💨
【Azure】異なるリージョン間でのAppServiceとAzure Database for MySQLの接続が失敗する場合の対処方法
概要
2025年2月現在、東日本リージョンのAppServicePlanが枯渇していることがあり、AppServicePlanを西日本リージョンにデプロイし、Azure Database for MySQLは東日本リージョンでデプロイしている状況です。その際に仮想ネットワーク統合、仮想ネットワークのピアリング、NSGやサブネットの設定に誤りがないにもかかわらず、AppServiceからAzure Database for MySQLへのPython処理が失敗している事象がありました。
構成
確認したこと
- 特に西日本リージョンでデプロイしたAppServicePlanの仮想ネットワーク統合は同じリージョンでしか設定ができないので西日本リージョンの仮想ネットワークを設定しています。
- サブネットの確認(こちらも特に問題は無し)
- ピアリングの設定。東日本リージョンと西日本リージョンの仮想ネットワークを接続するために必要な設定。(これも問題なし)
- NSG設定(こちらも特に問題は無し)
原因
- 仮想ネットワークやNSG周りは問題なかったため、Application Insightsを用意し、アプリケーションログを出力させたところ、下記のエラーが表示されました。
(pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on '<MySQLのリソース名>.mysql.database.azure.com' ([Errno -2] Name or service not known)")
(Background on this error at: https://sqlalche.me/e/20/e3q8)
エラーメッセージから、Azure App Service から Azure Database for MySQL への接続時に DNS 名の解決ができていないと判断。
-
AppServiceの[開発ツール]>[高度なツール]>[移動]の手順を実施し、[Bash]をクリック。
-
コンソールに入った後に下記のコマンドを実行。
nslookup <MySQLのリソース名>.mysql.database.azure.com
- 名前解決がされていないことが発覚。
** server can't find <MySQLのリソース名>.private.mysql.database.azure.com: NXDOMAIN
- 調査結果、デフォルトだとAzureの名前解決を使用して、ピアリングされた仮想ネットワークで名前を解決することはできないことが判明。下記URL参照。
https://learn.microsoft.com/ja-jp/azure/virtual-network/virtual-network-manage-peering?utm_source=chatgpt.com&tabs=peering-portal
対処方法
-
「プライベートDNSゾーン」に入る。
-
[<MySQLのリソース名>.private.mysql.database.azure.com]をクリックする。
-
[DNSの管理]>[仮想ネットワークリンク]をクリックする。
-
[追加]をクリックする。
-
下記の情報を設定し、[作成]をクリックする。
- リンク名
- サブスクリプション
- 仮想ネットワーク(今回は西日本リージョンの仮想ネットワークを設定)
※他の情報は特に設定しなくて大丈夫です。
-
「仮想ネットワーク」に入る。(手順6~8は東日本リージョンと西日本リージョン両方の仮想ネットワークで実施します)
-
[設定]>[DNSサーバー]をクリックする。
-
下記の設定をし、[保存]をクリックする。
- DNS サーバー : カスタム
- IP アドレス : 168.63.129.16
※"168.63.129.16"は Microsoft が保有するパブリック IP アドレスであり、Azure データーセンター上でのみ利用している仮想 IP アドレスで、Azure 上の名前解決 のための再帰的リゾルバー (フルサービス リゾルバー) の機能を提供しています。下記の用途で利用できます。- インターネット上のドメインに対する名前解決
- プライベート DNS ゾーン の名前解決
- 同一仮想ネットワーク上のホスト名での名前解決
https://jpaztech.github.io/blog/network/dns-168-63-129-16/
- 再度、AppServiceのコンソールに入り、下記のコマンドを実行。
nslookup <MySQLのリソース名>.mysql.database.azure.com
- 名前解決されていることを確認する。
Name: <MySQLのリソース名>.private.mysql.database.azure.com
Address: <プライベートIPアドレス>
- その後、AppServiceからAzure Database for MySQLへのPython処理がエラーなく成功しました!!
まとめ
- まとめると下記のようになります。
- Azure Database for MySQLのプライベートDNSゾーンに西日本リージョンの仮想ネットワークとリンクをしていなかったので紐づけ設定。
- 東日本リージョンと西日本リージョンの仮想ネットワークのDNSサーバーの設定をカスタムとし、"168.63.129.16"のIPアドレスを設定することで東日本リージョンと西日本リージョンの仮想ネットワーク間の名前解決ができるようになり、異なるリージョンでもAppServiceとAzure Database for MySQLの接続ができました。
Discussion