Web App, Front Door, Storage AccountをPrivate Endpointでつなぐ

# 最初に
Private Endpointの設定の仕方で毎回混乱するので自分用のメモ。色々な設定が必要で手順がかなり長くなってしまった。
Private Endpointの作成についてはいろいろ記事があるんだけど、Front Door, Web App, Storage Accountという構成のものを見たことないのでまとめる。

他にKeyVault、NSG等も使ったほうがいいので、このままの設定だと本番では使えない。これはあくまでもPrivate Endpointを使うためだけのサンプル構成です。

雑だけどこんなイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/80b4b8f0-2e21-09a5-c24f-bfea8ca18f52.png)

# リソースデプロイ
前提として、Front DoorはPremiumでないとPrivate Endpointの接続をサポートしていないので注意。

https://learn.microsoft.com/ja-jp/azure/frontdoor/standard-premium/tier-comparison

https://azure.microsoft.com/ja-jp/pricing/details/frontdoor/

Premiumは2023年現在330ドルするので中々いいお値段になってしまう。
ただし、それはそれだけFront Doorの機能が豊富であるということでもある。昔だったらTrafiic Manager、 Firewall、CDN、Application Gateway、DDos Protection等を組み合わせていた。

多機能過ぎてすごい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/d62de6f7-bf24-fe64-aa7b-e67325890f9f.png)

参考までにロードバランシングのオプション。

https://learn.microsoft.com/ja-jp/azure/architecture/guide/technology-choices/load-balancing-overview


## 手順
参考リンク。

https://learn.microsoft.com/ja-jp/azure/frontdoor/private-link

https://learn.microsoft.com/ja-jp/azure/frontdoor/quickstart-create-front-door

ざっとこんな感じ。
1. Resource Groupの作成
1. Vnet, Subnetの作成
1. App service planの作成
1. Web Appの作成
1. Front Doorの作成
1. Storage Accountの作成（実際はDatalakeを使う）

### Resource Group
まずはResource Groupの作成だけど、使えるRegionが限られている。

https://learn.microsoft.com/ja-jp/azure/frontdoor/private-link
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/4dd607bf-aef5-3261-f9ea-a8ffffb5ad93.png)
今回はJapan Eastを選択。（スクショ忘れた。）

### Vnet、Subnet
Private EndpointのためにVnetとSubnetを作る。
サブネットはWeb App用とStorage Account用を分ける。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/44dd22ea-3bf5-7805-72ca-766f3478fff9.png)

### App Service Plan
一旦BasicのLinuxを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/c5318fa2-210e-657e-7f0f-b85910868983.png)

### Web App
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/1ededae0-f92f-fabc-16c9-3362941dc501.png)

### Front Door
多分この辺は変わるんだろうけど。
色々設定があってややこしい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/9a82fd51-77bc-e0d7-26e8-17e9e93d771b.png)
Front DoorのProfileを作る。Premiumを選ぶ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/3347a3c0-b483-d797-0795-57236302ed65.png)
Endpoint作成してこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/cd129d2e-ad9b-5111-15e3-4ec22892faa3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/067236da-1950-2acc-3a1b-8e25f28e0677.png)
Route
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/8e1d3d1c-7251-98a1-0fb0-9f58208558a2.png)
Origin Group
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/12646384-c302-a655-ad28-8e1515acc8a4.png)
Origin、ここでPrivate link serviceを有効にする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/10a9a527-bed8-14de-39f6-c546407d216c.png)
最終的にこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/8f533a41-4947-6fcd-dc17-366ca903c04b.png)

記事用に試していたときは早くデプロイされたけど、Front Doorはグローバル分散サービスなので、Deployや設定変更に15分位かかるときもあった。中々Try & Errorするのも楽ではない。

### Storage Account
基本的に全てデフォルト設定でいく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/dbf0f17f-6279-230f-289f-13a5decf81bb.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/bdb9243e-3978-b325-ec6d-8e8ccf49fda2.png)

最終的にRGの一覧を見てみるとこんな感じになった。
ここには見えてないけどあとPrivate DNS Zoneもある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/1be64ead-213e-17c3-2ac4-072d802a399b.png)

一覧にはないが、実はWeb App用のPrivate Endpointは裏でDeployされている。Web AppのNetworking > Private Endpointを見るとこんな感じにでPendingになっている。こいつは承認してやる必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/49309b3c-0910-3144-bf4e-4185f2c65fa3.png)

ApproveするとNetworkingページがグリーンになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/07a805ef-4201-0c62-5bfb-8945e9c56edf.png)

警告メッセージとして、パブリックアクセスできなくなるよ＝Front Door経由でしかアクセスできなくなるよ、と表示さrれる。
> When you enable private endpoints, app assigned address inbound traffic feature is no longer applicable and will be turned off.
 
Private Endpointを開くとNo accessになる。これはFront Door側で管理しているから、ということと思われる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/53a85f8f-795c-a952-bc11-3cdf15b05498.png)

## 動作確認
Web AppのDefault Domainをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/e736cc36-e12e-0599-4982-0ec91240a52e.png)
あれ、接続できてしまう。。。これ以降何回か再起動したり、待ってみたり試したが、どうしてもパブリックアクセスできてしまっていた。
仕方ないので後続のステップで塞ぐことにする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/7cf481f7-bff3-3505-5630-9c202d698784.png)

今度はFront DoorのEndpoint hostnameのURLにアクセス。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/d1436dbd-5ed1-77e0-8c0b-85bb8a2c94f9.png)
Front Door経由で接続できることを確認。

ちなみにPrivate EndpointのApproveを忘れるとこんなエラーになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/de41c181-d606-211e-9276-3d1779de74df.png)

# 個別設定
個々のサービスを設定していく。
1. Storage AccountのNetworking設定
1. Web Appの設定

### Storage AccountのNetworking設定
まずはPublic Accessをふさぐ。
全部塞いでしまうとPortalやStrorage Explorerからもアクセスできなくなってしまうので、自分のIPのみ開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/a50f30ad-f7d3-a85a-0200-7de2e96bb68d.png)

Networking > Private EndpointsからPrivate Endpointを作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/fb530385-ed73-37c6-2197-e3e02bcfbfae.png)
今回はDatalakeにしたので、その場合はサブリソースのdfsとblobの両方が必要とのこと。

https://learn.microsoft.com/ja-jp/azure/storage/common/storage-private-endpoints

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/99aaf71e-c68f-ca46-7485-33b2a32e4a67.png)

Private Endpointを作る際には一緒にNicも作って、NicをSubnetに接続する。また、Private DNS Zoneを有効にする。

こっちは自動的にApproved状態になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/9bec7a7d-b381-93d4-2966-e4855919f5a1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/97b3f76e-c038-bacb-0a9e-ea2faafa992d.png)

### Web Appの設定
相変わらずPublicアクセスできてしまうこいつをFront Door経由だけのアクセスに絞りたい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/e40ea455-717e-5cc5-6e20-570335412849.png)

Networking > Access Ristrictionを確認する。
Main siteとAdvanced tool siteの2種類があるが、Main siteはパブリックアクセス不可に、Advanced tool site（Kudu）はデバッグとかで使うので、IP制限をかける。

#### Main site
- Unmatched rule actionをDenyに。
- デフォルトだとアクセス全て許可するAllow Allのデフォルトルールを変更。

https://learn.microsoft.com/ja-jp/azure/app-service/app-service-ip-restrictions?tabs=azurecli

Azコマンドでデフォルトルールを変更。
````
az resource update --resource-group rg-study001 --name wapp-study001 --resource-type "Microsoft.Web/sites" --set properties.siteConfig.ipSecurityRestrictionsDefaultAction=Deny
````

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/0f2342bc-b63e-157a-cd20-89f879036dce.png)

Web AppのURLをたたくとエラーになることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/350f77ff-c132-c259-4173-b9d2f8ddf4bb.png)

同時に（スクショはないが、）Front DoorのEndpoint経由だとつながることを確認。

#### Advanced tool site
Web Appのログを見れたり、デプロイのエンドポイントになったりするので、完全にふさいでしまうと不便。ただKudu裏からアクセスされてしまうと致命的なので、いったん自分のIPだけ許可するようにする。

    az resource update --resource-group rg-study001 --name Awapp-study001 --resource-type "Microsoft.Web/sites" --set properties.siteConfig.scmIpSecurityRestrictionsDefaultAction=Allow

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/3a7cec40-3591-2380-eeca-0c9bbd765671.png)

これでOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/e4ede9d3-e3a9-665d-762e-cf138bd0901c.png)

### Storage Accountの設定
さて、次にStorage AccountのPrivate edpoint を呼び出すためにはNetworking > Vnet integrationをONにする必要がある。

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

>  App Service の仮想ネットワーク統合機能を使用すると、アプリは仮想ネットワーク内のリソースにアクセスしたり、仮想ネットワークを通じてリソースにアクセスしたりできます。

Storage AccountのPrivate EntpointはNicでVnetに接続されているので、Web Appからそいつを呼び出すのにVnet統合が必要。SubnetはAppのものにつなぐ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/74631367-5e1f-a7b8-921e-24cb6fdf72f6.png)

## 動作確認
Storage Accountのdfs用のPrivate Endpoint > DNS configuration > FQDNをコピる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/ca98f9f9-5ddd-1f50-971e-1a4fb8874276.png)
dlstudy001.dfs.core.windows.net

ここで最初自分は勘違いしていたんだけど、privatelink...を含むURLを使う必要はない。通常のエンドポイントのURLを使えば裏で自動的にPrivate Endpointを使ってくれるのがいいところ。既存のサービスの接続を裏でPrivate Endpointを利用するように変更する場合も、URLの変更は不要で済む。

Advanced Tools > Go > Bashを開いてnslookupするとちゃんとPrivate IPで名前解決できていることが確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/72542bb1-276a-1d0b-08b3-19c9c7e1b2ef.png)

※ちなみに別のResource Groupで同じようなPrivate Endpointを使う構成のものがあった場合、ポチポチしているだけだと自動的にはうまくいかなかった。
Azure DNS ZoneはGlobalなリソースのため、設定がResource Groupをまたいでしまい、影響が出てしまう可能性があるので注意が必要。Resource Groupをまたいでいたとしても、vnet名やIP範囲が被らないようにするとか。

## Web AppにアプリをDeploy
最後にWeb Appにアプリをデプロイし、Web AppからDatalakeに接続できていることを確認する。

https://learn.microsoft.com/ja-jp/azure/storage/blobs/data-lake-storage-directory-file-acl-dotnet