Azure App Service B1 に VNET 内からのプライベートアクセスを試してみた

Azure App Service に VNET 内からパブリックに出ずプライベートアクセスするには、App Service Environment を使わないとダメだと記憶していました。最近調べてみると B1 サイズでもプライベートエンドポイント経由で VNET 内からプライベートアクセスできるみたいなので試してみました。

## 検証用の Azure App Service B1 を作成

```bash:bash
prefix=mnrpe
region=japaneast

az group create \
  --name ${prefix}-rg \
  --location $region

az appservice plan create \
  --name ${prefix}-plan \
  --resource-group ${prefix}-rg \
  --is-linux \
  --sku B1

az webapp create \
  --name ${prefix}-app \
  --resource-group ${prefix}-rg \
  --plan ${prefix}-plan \
  --runtime "PHP|8.2" \
  --https-only true

az webapp config set \
  --name ${prefix}-app \
  --resource-group ${prefix}-rg \
  --always-on true \
  --ftps-state Disabled

echo test > index.html

zip zipdeploy.zip index.html

az webapp deployment source config-zip \
  --name ${prefix}-app \
  --resource-group ${prefix}-rg \
  --src zipdeploy.zip

curl -s https://${prefix}-app.azurewebsites.net

# test と表示される
```

## VNET を作成

```bash:bash
az network vnet create \
  --name ${prefix}-vnet \
  --resource-group ${prefix}-rg \
  --address-prefixes 10.0.0.0/24

az network nsg create \
  --resource-group ${prefix}-rg \
  --name ${prefix}-nsg

az network vnet subnet create \
  --resource-group ${prefix}-rg \
  --vnet-name ${prefix}-vnet \
  --name app-subnet \
  --address-prefix 10.0.0.0/26 \
  --network-security-group ${prefix}-nsg
```

## プライベートエンドポイントを作成

```bash:bash
webappid=$(az webapp show \
  --name ${prefix}-app \
  --resource-group ${prefix}-rg \
  --query id \
  --output tsv)

az network private-endpoint create \
  --connection-name connection-1 \
  --name private-endpoint \
  --private-connection-resource-id $webappid \
  --resource-group ${prefix}-rg \
  --vnet-name ${prefix}-vnet \
  --subnet app-subnet \
  --group-id sites \
  --ip-config name=ipconfig-1 group-id=sites member-name=sites private-ip-address=10.0.0.10

az network private-dns zone create \
  --resource-group ${prefix}-rg \
  --name privatelink.azurewebsites.net

az network private-dns link vnet create \
  --resource-group ${prefix}-rg \
  --zone-name privatelink.azurewebsites.net \
  --name dns-link \
  --virtual-network ${prefix}-vnet \
  --registration-enabled false

az network private-endpoint dns-zone-group create \
  --resource-group ${prefix}-rg \
  --endpoint-name private-endpoint \
  --name zone-group \
  --private-dns-zone privatelink.azurewebsites.net \
  --zone-name webapp
```

## パブリック経由のアクセス状態を確認

プライベートエンドポイント作成時点で Azure App Service へのパブリックアクセスが制限されるようです。

```bash:bash
curl -I https://${prefix}-app.azurewebsites.net

# HTTP/2 403 と表示される
```

## 接続元となる検証用の VM を作成

```bash:bash
az vm create \
  --resource-group ${prefix}-rg \
  --name ${prefix}-vm \
  --os-disk-name ${prefix}-vmOSDisk \
  --image Ubuntu2204 \
  --size Standard_B1s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-address "" \
  --nsg-rule NONE \
  --vnet-name ${prefix}-vnet \
  --subnet app-subnet
```

## VNET 内からのプライベートアクセスを試す

```bash:bash
az vm run-command invoke \
  --resource-group ${prefix}-rg \
  --name ${prefix}-vm \
  --command-id RunShellScript \
  --scripts "curl -s https://${prefix}-app.azurewebsites.net" \
  --query "value[].message" \
  --output tsv
```

以下のように `test` という index.html 内のテキストを取得する事ができました。

```bash:bash
Enable succeeded: 
[stdout]
test

[stderr]
```

## 検証環境の片付け

```bash:bash
az group delete \
  --name ${prefix}-rg \
  --yes
```

## 参考

https://learn.microsoft.com/ja-jp/azure/app-service/networking/private-endpoint

https://learn.microsoft.com/ja-jp/azure/private-link/create-private-endpoint-cli?tabs=static-ip