Azure NATゲートウェイの冗長構成を検討する

## AzureのNATについて
Azureではデフォルトで[SNATされる仕組み](https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-outbound-connections#scenario-3-standalone-vm-without-a-public-ip-address)があり、パブリックIPを持たないVMからでも外部へアクセスすることが可能です。
しかしながら、この仕組みではIPアドレスが動的に変化してしまいます。（詳細説明は省略します）

Azure上の仕組みでIPアドレスを固定する方法は何パターンか存在しますが、
NATゲートウェイが最近リリースされたようですのでこのリソースを利用したIPアドレス固定を考えます。

AWSのNATゲートウェイと同様である（と想定される）AzureのマネージドNATゲートウェイ、
その構築手順と冗長構成について簡単に纏めます。

- NATゲートウェイ: https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-nat-gateway.html
- Virtual Network NATとは: https://docs.microsoft.com/ja-jp/azure/virtual-network/nat-overview

## 検証環境
パブリックIPを持つVMと持たないVMを作成し、そのサブネットへのNATゲートウェイ紐付け前後で変化を確認します。
※ ここではvm01を踏み台にしてvm02にsshします。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631110/9da22dfd-bbfd-7c0f-4289-0399c93f7d36.png)


```sh
# パブリックIPを持つVM
[root@centos-vm01 ~]# curl ifconfig.me
40.81.187.139

# パブリックIPを持たないVM（SNATされる）
[root@centos-vm02 ~]# curl ifconfig.me
40.74.79.8
```


## NATゲートウェイを構築する
Azure NATゲートウェイでは、1つのNATゲートウェイを複数のサブネットに紐づけることが可能です。
※ 当然ですが、1サブネットに複数のNATゲートウェイを紐づける事は不可能です

検索バー等で検索してNATゲートウェイを作成していきます。
<img width="1250" alt="screenshot 2020-05-04 1.10.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631110/43c462fb-3c73-fbb1-2830-38ffcdec75e9.png">

可用性ゾーンではゾーン指定なし、もしくはいずれかのゾーンを指定します。
<img width="841" alt="screenshot 2020-05-04 1.22.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631110/c4e3560d-a98f-afa0-eb7f-f0d390fb2ca1.png">


紐づけるサブネットはNATゲートウェイ作成時に指定できますが、リソースの作成後でも修正可能です。
<img width="840" alt="screenshot 2020-05-04 1.23.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631110/c45c873a-f5bf-8543-ebed-a9d82dca0733.png">

サブネットへの紐付け後、各VMから再度送信元IPアドレスを確認すると、
NATゲートウェイのパブリックIPアドレスでSNATされていることが確認できます。
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631110/45f63f3b-a547-99e8-ee7f-8e5d8547d115.png)

```sh
# パブリックIPを持つVM
[root@centos-vm01 ~]# curl ifconfig.me
40.74.111.48

# パブリックIPを持たないVM
[root@centos-vm02 ~]# curl ifconfig.me
40.74.111.48
```


## 冗長構成について
NATゲートウェイを作成する際に可用性ゾーンを指定していましたが、なしで指定した場合でも内部ではゾーン1,2,3のいずれかにデプロイされています。
そのため可用性ゾーンレベルでの障害が起こった場合、1/3で障害をNAT環境に影響を及ぼすことになります。（単純計算ではありますが）

AWSではAZを指定してサブネットを作成しますので、AWSでのNAT環境のAZ冗長を考えると、
AZを分けたサブネットに対して同様にAZを分けたNATゲートウェイリソースを作成することになります。

一方でAzureでは、サブネットが可用性ゾーンを跨る様に構成されています。
ここでAWSと同様にゾーンを分けて構成（ゾーン保証）することを考えます。
https://docs.microsoft.com/ja-jp/azure/virtual-network/nat-gateway-resource

[ドキュメント中](https://docs.microsoft.com/ja-jp/azure/virtual-network/nat-gateway-resource#availability-zones
)でも説明されていますが、ゾーンを分けてNAT環境を構築する場合は下記の方法となります。

- ゾーン冗長したい数だけサブネット、NATゲートウェイを作成する
- サブネットに紐付けているNATゲートウェイと同じゾーンを指定してVMを立ち上げる

![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631110/6df585ce-bbf8-d75a-afcb-5bb20ff914ca.png)

ゾーン毎のスタックを構成することでゾーン冗長を考慮した構成になります。
上記構成では、可用性ゾーン1で障害が発生しても、az2-subnet/az3-subnet上のVMには影響がありません。
（az1-subnetに対して、可用性ゾーン2/3を指定してVMを立ち上げること自体は可能です）

## 最後に
AWS、AzureのNATゲートウェイはゾーン冗長を考慮しなくとも、99.9%以上のSLAで提供されています。

- https://aws.amazon.com/jp/vpc/sla/
- https://docs.microsoft.com/ja-jp/azure/virtual-network/nat-overview#sla

一般的な用途では十分とは思いますが、
アプリケーションの要件でゾーン冗長が必要な場合には、上記の様な構成も一考の余地があるかもしれません。

しかしながら、Azureではサブネットが可用性ゾーンを跨ぐように設計されていますので、
サブネットに対してデプロイするゾーンを決めてVMを立ち上げることが設計思想上正しいかどうかは不明です。。