Azure App Service の VNet 統合 を試す！！(半閉域化)

こんにちは、アーキテクトのやまぱんです。
今回は Azure App Service の VNet 統合を試してみたいと思います。
<span style="font-size: smaller;">（とはいっても結構まえに試しており、記事執筆開始時点ですでに環境はないですが、放流します)</span>

補足コメントや質問、<font color="red">いいね、拡散</font>、是非お願いします🥺！
間違ってたら<font color="red">優しく</font>教えてください！


ちなみに Private Endpoint を試した記事はこちらになります。

https://qiita.com/aktsmm/items/9ab681f82d81aae504df


# まえおき
## Azure App Service とは
言わずもがな、 Azure を代表する PaaS サービスです。
マネージドはウェブアプリホスティングサービスです。
スケーラビリティやCICD連携などの機能もあってイチオシです

+ 公式ドキュメントはこちら

https://learn.microsoft.com/ja-jp/azure/app-service/overview

+ 内部的な仕組みはこちら

https://qiita.com/mym/items/1d364c0251daf88d417d

+ 日本マイクロソフトの公式　Youtube はこちら
 「**Azure といえば　PaaS ですよ！！！！！！**」
 
https://www.youtube.com/watch?v=NGINCpzvztE


## VNet 統合 (VNet Integration) とは
Azure App Service をはじめ、PaaS サービスは基本的にパブリック IP がデフォルトで存在し、パブリックIP を通して通信するようになっています。
VNet 統合を利用することで PaaS サービスが VNet へアクセスできるようにする機能です。
VNet とは Azure 上のユーザーのプライベートネットワーク空間です。

## Azure App Service における VNet 統合 (VNet Integration) とは
まず、ポイントとして、**Azure App Service は 送信用の IP と受信用の IP があります。**
Azure Portal → Azure App Service の概要のページでは以下のように確認できます。
　仮想IPアドレスが受信用のアドレス、送信IPアドレスがそのまま送信用のアドレスです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/fbae3e69-4aa2-c0e5-0195-17248e5db5b3.png)


このことは下記のあたりに記載されています。
https://qiita.com/mym/items/1d364c0251daf88d417d#%E3%83%91%E3%83%96%E3%83%AA%E3%83%83%E3%82%AF-vip

そして、VNet 統合は PaaS から VNet への通信 (つまりプライベートIPでの通信)を可能にするものです。
なので、**VNet 統合を使って、VNet から PaaS への通信をプライベートな通信にすることはできません。** その際には Private Endpoint を使います。とっても大事です。

## VNet 統合 (VNet Integration) と Private Endpoint と Service Endpoint
ここで 似たような名前の Service Endpoint も入れて、VNet 統合 と Private Endpoint の違いを簡単に表にしておさらいします。
|名前|対象の通信|プライベート IP かパブリック IP か|
|:-|:-:|:-|
|VNet 統合|<font color="red">PaaS → VNet</font>(*)|宛先・送信元ともに プライベートIP|
|Private Endpoint |VNet → PaaS |宛先・送信元ともに プライベートIP|
|Service Endpoint |VNet → PaaS |宛先はパブリック IP / 送信元はプライベートIP|
|補足|*リソースによっては VNet 統合が送受信ともにPrivate IP 通信可能にするものもあります。|

その他、Private Endpoint と Service Endpoint の詳しい違いについては下記を参考にしてください。

https://jpaztech.github.io/blog/network/pe-difference-se/

# Azure App Service の VNet 統合 を試してみる
フリーハンドな絵で大変大変恐縮ですが、太線の **Azure App Service からVNet(Azure VM)への通信**を今回 VNet 統合によって実現させて、実際に確認してみます。
細線部分は VNet 統合前の Public IP を使った経路です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/b021cc23-31f7-0eba-c36e-ba1e477b6230.png)

## 準備
・Ubuntu + python3 で Web サーバー を立ち上げておきます。

```bash:簡易Webサーバー構築手順
# "www"という名前のディレクトリを作成します。
mkdir www
# "www"ディレクトリに移動します。  
cd www  
# "index.html"という名前のファイルを作成します。これは後で作成するウェブページのメインのHTMLファイルです。
touch index.html  
# "index.html"ファイルに"<h2>Hello yamapan test page</h2>"というHTMLコードを書き込みます。
echo "<h2>Hello yamapan test page</h2>" > index.html  
# "index.html"ファイルの内容を表示します。これにより、"Hello yamapan test page"というテキストが含まれることが確認できます。
cat index.html  
# 現在のディレクトリ（wwwディレクトリ）をルートとするHTTPサーバーをポート80で立ち上げます。
sudo python3 -m http.server 80  
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/5d0d470f-c2f4-66c8-0bdb-20dadb3f862f.png)
*Hello のスペルが間違ってますが、今回の検証には問題ではないので気にせず進めます。👌
Public IP アドレスは ```52.140.204.171```です。
Private IP アドレスは ```10.0.0.4```です。

・Azure VM が属する VNet に**事前にVNet 統合用の空のサブネット"Subnet-AppInteg"** を構成済み。後ほどVNet 統合する際にサブネット委任する必要があり、そこで利用します。
作成していない場合は作成してください。

・デフォルトの設定で App Service は構築済
味気ないですが今回はこのまま Go 😀
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/7938a03e-e96e-e994-cdc8-6083b0737bdf.png)

## デフォルトのパブリックアクセス
 App Service では、App Service に Azure Portal 経由で SSH 接続することができます。
 これを使ってまず、VNet 統合を構成する前の状態で Azure VM への通信を見ていきます。

+ App Service 側 から Azure VM の Pubic IPへ curl 

```
curl -i http://52.140.204.171
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/3dcfa477-507f-20a0-f9bc-86628ee88c21.png)

Webサーバ側確認、App Service の **アウトバウンド 用の Public IP 20.27.133.99** を使ってAzure VM (Webサーバ) にアクセスしてることが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/5b194590-bbfd-d154-77bd-8f454beff15c.png)

ちなみにこれは、 "Azure App Service" → "ネットワーク" から確認できる送信トラフィックの構成-送信アドレス に記載されている IP アドレスに含まれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/1470b820-473f-4625-9cd8-19d9d4f56d2c.png)


**この Azure VM  へのアクセスが Public IP ではなく Private IP からアクセスできるようになれば OK 🤞それを今回は確認します。**

## VNet 統合 (VNet Integration) の構成
ここから VNet 統合していきます。
**事前にVNet 統合用の空のサブネット"Subnet-AppInteg"** を構成済みです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/5a87e83d-1573-da30-fcbf-f58c2ef21b66.png)

ここで準備しておいた空の Subnet "Subnet-AppInteg" を選択します。
**メッセージが出ているように空の Subnet でないと指定できません。**

そして、「接続」をクリック！！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/25034df0-9da5-afbb-6fff-11a5e5125511.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/bfd211cf-29aa-d4b5-952c-bd7e9db00d81.png)

数秒で完了し、下記のような画面になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/8cc7092a-e3d9-f8b1-6300-a02b9e9be9e5.png)
今回はこんな感じです。

:::note
VNet 統合の送信インターネット トラフィック について
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/361fa91f-5d6c-c60e-e095-7141568e6fdf.png)
+ 上記にチェックを入れている場合：VNet側にインターネットへのアウトバウンドもルーティングされるので疎通不可 → VNet(NSGなど)で通信制御できる
+ 上記にチェックを入れていない場合：VNet側にインターネットへのアウトバウンドはルーティングされず、直接インターネットに抜けるので疎通可能 → 制御できない
:::

ここで対象のVNetを確認してみましょう。👍
サブネット：**Subnet-AppInteg** がAzure App Serviceに委任されていることが分かります。
これがいわゆる　サブネットの委任 ってやつですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/60e0662f-13b5-2107-83c7-c5e710600140.png)

## VNet統合環境でのプライベートアクセス
では App Service から Webサーバへ Private IP で curl してみましょう。
先ほど実施したように、Azure Portal からブラウザ越しにSSHして curl してみます。

```
curl http://10.0.0.4
```

下記の通りPrivate IPで通信できていることが分かります。
**期待通りの結果！！**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/22781101-562b-5b91-21db-75398ed4806a.png)

Webサーバ側 でも Private IP からのアクセスが記録されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/4d6842aa-7662-8c6c-bd98-0dd29f516dd5.png)




# 参考
VNet 統合に関する詳細は下記をご確認ください。

https://learn.microsoft.com/ja-jp/azure/app-service/overview-VNet-integration

> 仮想ネットワーク統合を使っている場合は、次の Azure ネットワーク機能を使用できます。
ネットワーク セキュリティ グループ (NSG) :統合サブネットに配置された NSG を使って送信トラフィックをブロックできます。 仮想ネットワーク統合を使ってアプリへの受信アクセスを提供することはできないため、受信規則は適用されません。
ルート テーブル (UDR) :統合サブネット上にルート テーブルを配置して、必要な場所に送信トラフィックを送信できます。
NAT ゲートウェイ: NAT ゲートウェイを使うと、専用の送信 IP を取得し、SNAT ポートの枯渇を軽減できます。

本件に関連するAzure App Service の Private Endpoint の内容を下記動画で解説してくれています。

https://www.youtube.com/watch?v=ekZfLqEnI4I


そもそも前提として、Azure App Service のインフラ周りについてはこちらを確認していただけるとよいかと思います。
https://www.youtube.com/watch?v=lun-KPAHvi4&list=PLQEKit6tfVVI6cl89K8rQ2gkW8dpbOCML&index=6




# あとがき
ということで Azure App Service のアウトバウンド通信を制御、Private IP 経由 (VNet経由)にすることができました。
しかし～！このままでは Azure App Service へのインバウンド通信は Public IP 経由の経路しかありませんす。

なのでつづいて、Azure App Service へのインバウンド通信を VNet からPrivate I P経由にしてみましょう。
つまり Private Endpoint を利用して、完全閉域化してみましょう、、、これはまたオイオイ書きたいと思います。（オイオイ！