Azure Storage のリージョンを跨いだサービスエンドポイントを試す

Azure の仮想ネットワークから Azure Storage へアクセスする際にサービスエンドポイントとストレージ側のファイアウォールを使うことで特定の仮想ネットワークからのみにアクセスを制限することができますが、この機能は現状、同一リージョンまたはペアリージョンへのアクセスのみサポートとなっていました。以下のリンクにある通り、任意のリージョンへのアクセスがパブリックプレビューで利用できるようになりましたので、さっそく試してみました。

https://azure.microsoft.com/en-us/updates/service-endpoints/

2023/4/25 に GA となりました。

https://azure.microsoft.com/en-us/updates/generally-available-crossregion-service-endpoints-for-azure-storage/

構成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/9681fadb-e10c-fa9f-9638-0e9f94f1d49d.png)

#サービスエンドポイントのメリット
上記のようなリージョンを跨いだ構成の場合、パブリック IP アドレスにて送信元を制御することもできますが、Azure Storage へのサービスエンドポイントを利用することで、以下のようなメリットもあります。

- ストレージへのアクセス経路の最適化
    - 例えば強制トンネリング構成の際にストレージへのアクセスはバックボーン経由にしたいといった構成で UDR を使わずに対応可能
- パブリック IP アドレスによる SNAT がない
    - LB や Firewall の SNAT 枯渇を防止
    - ソース IP アドレスの特定
- パブリック IP アドレスが不要
- サブネット単位で許可させることができる
    - サブネット内の VM は任意にアクセスできるようになるため、個別のアクセス制御も不要となる

<font color="Red">※アクセス元のリソースと Azure Storage のリージョンが同じ場合はパブリック IP アドレスからは Azure Storage にアクセスできませんので注意が必要です。</front>

#検証手順
プレビューの登録手順は以下にあります。

https://docs.microsoft.com/en-us/azure/storage/common/storage-network-security?tabs=azure-powershell#enabling-access-to-virtual-networks-in-other-regions-preview

現状、Azure Powershell または Azure CLI でやる必要があります。

```
Connect-AzAccount

Set-AzContext -SubscriptionId <サブスクリプション ID>

Register-AzProviderFeature -ProviderNamespace Microsoft.Network -FeatureName AllowGlobalTagsForStorage
```

以下の RegistrationState が "Registered" になるまで待ちます。(20-30 分かかりました。)

```
Get-AzProviderFeature -ProviderNamespace Microsoft.Network -FeatureName AllowGlobalTagsForStorage

FeatureName               ProviderName      RegistrationState
-----------               ------------      -----------------
AllowGlobalTagsForStorage Microsoft.Network Registering
```

仮想ネットワークのサブネットにストレージ用のサービスエンドポイント "Microsoft.Storage" を追加します。

```
Get-AzVirtualNetwork -ResourceGroupName "EREastUS" -Name "ERVNet" | Set-AzVirtualNetworkSubnetConfig -Name "VM-Subnet" -AddressPrefix "10.10.1.0/24" -ServiceEndpoint "Microsoft.Storage" | Set-AzVirtualNetwork
```

成功するとちゃんと登録されていることが確認できます。

```
                           "ServiceEndpoints": [
                               {
                                 "ProvisioningState": "Succeeded",
                                 "Service": "Microsoft.Storage",
                                 "Locations": [
                                   "*"
                                 ]
                               }
                             ],
```

この段階でポータルからサブネットの追加を試みましたが、対象のサブネットは表示されませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/ed55d66b-7e20-f0f0-8ca4-59e898ba8d83.png)


以下の 2 つのコマンドで、ストレージ側の Firewall に対象のサブネットを追加します。

```
$subnet = Get-AzVirtualNetwork -ResourceGroupName "EREastUS" -Name "ERVNet" | Get-AzVirtualNetworkSubnetConfig -Name "VM-Subnet"

Add-AzStorageAccountNetworkRule -ResourceGroupName "Storage" -Name "gzrshiyamasto" -VirtualNetworkResourceId $subnet.Id


Action VirtualNetworkResourceId                                                                                          State
------ ------------------------                                                                                          -----
 Allow /subscriptions/xxxxx/resourceGroups/EREastUS/providers/Microsoft.Network/virtualNetworks/ERVNet/subnets/VM-Subnet Succeeded

```

設定が、"すべてのネットワーク" のままだったので、"選択されたネットワーク" に変更してみると、上記で追加したサブネットが追加済みとして表示されたので、そのまま保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/7f9d30d8-edc5-4dec-80b9-9cba8ee828d9.png)

アクセスログ取得のため、診断ログを有効化しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/b5b60790-e3a0-3f36-575f-6f4e412a505f.png)

#動作確認
アクセス確認します。米国東部の VM から curl で問題なくアクセスできることを確認します。また、東日本の VM からアクセスしましたが、許可されてないため Status 403 になることも確認できました。

```
[testuser@EastUSVM ~]$ curl -v https://gzrshiyamasto.blob.core.windows.net/test/index.html
* About to connect() to gzrshiyamasto.blob.core.windows.net port 443 (#0)
*   Trying 20.38.117.228...
* Connected to gzrshiyamasto.blob.core.windows.net (20.38.117.228) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate:
*       subject: CN=*.blob.core.windows.net
*       start date: Oct 13 21:51:40 2021 GMT
*       expire date: Oct 13 21:51:40 2022 GMT
*       common name: *.blob.core.windows.net
*       issuer: CN=Microsoft RSA TLS CA 01,O=Microsoft Corporation,C=US
> GET /test/index.html HTTP/1.1
> User-Agent: curl/7.29.0
> Host: gzrshiyamasto.blob.core.windows.net
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length: 12
< Content-Type: text/html
< Content-MD5: bLL+2vK0uXm1HPdaivMY1w==
< Last-Modified: Fri, 10 Dec 2021 09:37:47 GMT
< ETag: 0x8D9BBC0B9F1A604
< Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
< x-ms-request-id: 60082f7b-101e-0065-4cb4-ed1d3b000000
< x-ms-version: 2009-09-19
< x-ms-lease-status: unlocked
< x-ms-blob-type: BlockBlob
< Date: Fri, 10 Dec 2021 10:53:40 GMT
<
* Connection #0 to host gzrshiyamasto.blob.core.windows.net left intact
Test BLOB
```

診断ログを確認します。ちゃんと VM の IP アドレス "10.10.1.4:43622" からアクセスがあることが確認できます。

```
1.0;2021-12-10T10:53:40.7513037Z;～省略～;  10.10.1.4:38580  ;～省略～, 10-Dec-21 09:37:47 GMT;;"curl/7.29.0";;
```

念のためサービスエンドポイントとストレージのファイアウォール設定を外した際のログも確認します。VM に割り当てたパブリック IP アドレスからアクセスがあることが確認できます。

```
1.0;2021-12-10T10:52:23.6285100Z;GetBlob;～省略～;   20.119.60.232:56374   ;～省略～, 10-Dec-21 09:37:47 GMT;;"curl/7.29.0";;
```

リージョンを跨いだサービスエンドポイント、ストレージのファイアウォールの動作確認が無事できました。