Azure App ServiceのVNET統合＋NAT Gatewayを試す

船井総研デジタルのよもぎたです。

# サマリ

この記事では、Azure App ServiceにNAT Gatewayを追加した仮想ネットワークを統合して、App Service上のWebアプリから外部のAPIなどにアクセスする際の送信元IPアドレスがNAT Gatewayのものになっていることを確認したいと思います。

仕組みとしてそうなるはずだけど、実際に確認しないと安心できない！というのが動機です。
結果としては、期待通りにNAT GatewayのIPアドレスから外部に通信していることが確認できました。

# 実際にやった確認手順

1. App Serviceをプロビジョニングする
1. 仮想ネットワークをプロビジョニングする
1. 仮想ネットワークにNAT Gatewayを追加する
1. Webアプリをプロビジョニングする
1. Webアプリに仮想ネットワークを統合する
1. Webアプリをデプロイする
1. Webアプリに外部にアクセスしてアクセス元IPアドレスを表示するページを作る
1. 追加作成したページにアクセスして、外部へのアクセスの際のIPアドレスを確認する

WebアプリはPythonのDjangoをベースにしました。
アクセス元IPアドレスの確認は [@G-awa](https://qiita.com/G-awa) さんの[こちらの記事](https://qiita.com/G-awa/items/b28bd16c95ff4ecfe441)を参考にさせて頂きました。

以下、具体的な手順です。

## App Serviceをプロビジョニングする

App Serviceプランをプロビジョニングする際に注意するのはOSと価格レベルです。OSは、Python/Djangoを動かしたいので、Linuxを選択します。価格レベルは、仮想ネットワーク統合ができるBasic以上を選択します。

## 仮想ネットワークとNAT Gatewayの準備

仮想ネットワークとNAT Gatewayについては検証用に新規に作成したこと以外はとくに注意すべきこと、変わったことはしていません。

## Webアプリをプロビジョニングする

Webアプリをプロビジョニングする際に注意するのは、「公開」とランタイムスタックです。公開は「コード」を、ランタイムスタックは``Python3.9``以降を選択します。

## Webアプリに仮想ネットワークを統合する

Webアプリをプロビジョニング出来たら、先ほど作成した仮想ネットワークに統合します。

Azure PortalでWebアプリを選択し、左のメニューの「ネットワーク」を選択し、続いて右のペインで「仮想ネットワーク統合」の右の「未構成」をクリックして構成メニューに入ります。

![スクリーンショット 2023-11-03 201734.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822136/d0437fc5-2d05-a25e-b6d9-42aa9c630436.png)

「仮想ネットワーク統合の追加」というボタンをクリックして表示されるメニューで、統合する仮想ネットワークとサブネットを選択して「接続」をクリックします。

これで、「仮想ネットワーク統合」と「NATゲートウェイ」に接続したサブネットとサブネットに関連付けたNATゲートウェイが表示されます。

## Webアプリをデプロイする

Webアプリは、Microsoft LearnのApp Serviceのドキュメントの[クイックスタートのサンプルアプリケーション](https://learn.microsoft.com/ja-jp/azure/app-service/quickstart-python?tabs=django%2Cmac-linux%2Cvscode-aztools%2Cvscode-deploy%2Cdeploy-instructions-azportal%2Cterminal-bash%2Cdeploy-instructions-zip-azcli)をベースにしました。

まずは手順の1から4までを実行して、App Servicve/Webアプリにサンプルアプリケーションをデプロイします。少し時間がかかるので待ちましょう。待っていればVSCodeの右下にデプロイしたWebアプリにアクセスする青いボタンが表示されます。アクセスするとサンプルアプリケーションのページが表示されます。

## Webアプリに外部にアクセスしてアクセス元IPアドレスを表示するページを作る

いよいよ本題のWebアプリから外部へのアクセスを追加します。[Djangoの公式ドキュメントのチュートリアル](https://docs.djangoproject.com/ja/4.2/intro/tutorial01/)を参考にしました。

まず、外部へのアクセスに[requests](https://pypi.org/project/requests/)を使うので、``requirements.txt``にパッケージ名を追加します。

```requirements.txt
Django
whitenoise
requests
```

つづいて、自身のIPアドレスを表示する``myipaddr``ページを作成します。

```Bash
$ python manage.py startapp myipaddr
```

``myipaddr``ディレクトリが作成されたら、``views.py``を次の内容に修正します。

```myipaddr/views.py
from django.shortcuts import render

# Create your views here.
from django.http import HttpResponse

import requests

def index(request):
    r = requests.get('http://checkip.amazonaws.com/')
    return HttpResponse(r.text)
```

次に``urls.py``ファイルを下記の内容で作成します。

```myipaddr/urls.py
from django.urls import path

from . import views

urlpatterns = [
    path("", views.index, name="index"),
]
```

続いて、``quickstartproject/urls.py``に``myipaddr.urls``モジュールを反映させます。

```quickstartproject/urls.py
---snip--- 
urlpatterns = [
    path('', include('hello_azure.urls')),
    path('myipaddr/', include('myipaddr.urls')),  # この行を追加します
    path('admin/', admin.site.urls),
]
---snip---
```

ここまで出来たら、再度アプリケーションをデプロイします。

## 追加作成したページにアクセスして、外部へのアクセスの際のIPアドレスを確認する

デプロイが完了したら、今度は``https://<appname>.azurewebsites.net/myipaddr/``にアクセスします。

ここでそっけなくNAT Gatewayに割り当てたパブリックIPアドレスが表示されれば成功です。

# 最後に

そういう仕様なんだから当然の結果だろう、と言ってしまえばそれまでですが、実際に動かしてみることで、自分が行った作業、今回で言えば前半のWebアプリと仮想ネットワークの統合が間違っていないことが確認出来て安心しました。

最後までお読みいただきありがとうございました。