プレビューのリージョン間ロードバランサー（Cross-region load balancer）を Azure CLI で作ってみた

## 背景と目的

リージョン間で負荷分散するのは Azure Front Door か Azure Traffic Manager でしたが、もう一つの選択肢として Cross-region Load Balancer が増えました。作ってみないとわからない事もあるので、早速試しに Azure CLI で作ってみました。

## リソースグループを作成

```bash:bash
# 環境変数をセットします
region1=eastasia
region2=japaneast
prefix=mnrcrlb

# リソースグループを作成します
az group create \
  --name ${prefix}-rg \
  --location $region1
```

## 東日本リージョンに VMSS を作成

```bash:bash
# VMSS を作成します（既定で 2VM 作成されます）
az vmss create \
  --resource-group ${prefix}-rg \
  --location $region2 \
  --name ${prefix}-jp \
  --image UbuntuLTS \
  --vm-sku Standard_B1s \
  --storage-sku Standard_LRS \
  --lb-sku Standard \
  --upgrade-policy-mode automatic \
  --admin-username azureuser \
  --generate-ssh-keys

# NSG ルールに HTTP ポートを追加します
az network nsg rule create \
  --resource-group ${prefix}-rg \
  --name Allow-HTTP \
  --nsg-name ${prefix}-jpNSG \
  --priority 100 \
  --destination-port-ranges 80 \
  --access Allow \
  --protocol Tcp

# VM に Nginx をインストールします
az vmss extension set \
  --publisher Microsoft.Azure.Extensions \
  --version 2.0 \
  --name CustomScript \
  --resource-group ${prefix}-rg \
  --vmss-name ${prefix}-jp \
  --settings '{"fileUris":["https://raw.githubusercontent.com/Azure-Samples/compute-automation-configurations/master/automate_nginx.sh"],"commandToExecute":"./automate_nginx.sh"}'

# LB の IP アドレスを取得します
vmjp=$(az network public-ip show \
  --resource-group ${prefix}-rg \
  --name ${prefix}-jpLBPublicIP \
  --query "ipAddress" \
  --output tsv)

# LB の IP アドレスにアクセスします
curl -s $vmjp
```

何回かアクセスすると以下のようにホスト名を含んだレスポンスを順番に返します。

```bash:bash
$ curl -s $vmjp
Hello World from host mnrcr6b95000003 !
$ curl -s $vmjp
Hello World from host mnrcr6b95000001 !
$ curl -s $vmjp
Hello World from host mnrcr6b95000003 !
$ curl -s $vmjp
Hello World from host mnrcr6b95000001 !
```

## 東アジアリージョンに VMSS を作成

```bash:bash
# VMSS を作成します（既定で 2VM 作成されます）
az vmss create \
  --resource-group ${prefix}-rg \
  --location $region1 \
  --name ${prefix}-hk \
  --image UbuntuLTS \
  --vm-sku Standard_B1s \
  --storage-sku Standard_LRS \
  --lb-sku Standard \
  --upgrade-policy-mode automatic \
  --admin-username azureuser \
  --generate-ssh-keys

# NSG ルールに HTTP ポートを追加します
az network nsg rule create \
  --resource-group ${prefix}-rg \
  --name Allow-HTTP \
  --nsg-name ${prefix}-hkNSG \
  --priority 100 \
  --destination-port-ranges 80 \
  --access Allow \
  --protocol Tcp

# VM に Nginx をインストールします
az vmss extension set \
  --publisher Microsoft.Azure.Extensions \
  --version 2.0 \
  --name CustomScript \
  --resource-group ${prefix}-rg \
  --vmss-name ${prefix}-hk \
  --settings '{"fileUris":["https://raw.githubusercontent.com/Azure-Samples/compute-automation-configurations/master/automate_nginx.sh"],"commandToExecute":"./automate_nginx.sh"}'

# LB の IP アドレスを取得します
vmhk=$(az network public-ip show \
  --resource-group ${prefix}-rg \
  --name ${prefix}-hkLBPublicIP \
  --query "ipAddress" \
  --output tsv)

# LB の IP アドレスにアクセスします
curl -s $vmhk
```

何回かアクセスすると以下のようにホスト名を含んだレスポンスを順番に返します。

```bash:bash
$ curl -s $vmhk
Hello World from host mnrcr5c1f000000 !
$ curl -s $vmhk
Hello World from host mnrcr5c1f000001 !
$ curl -s $vmhk
Hello World from host mnrcr5c1f000000 !
$ curl -s $vmhk
Hello World from host mnrcr5c1f000001 !
```

## 東アジアリージョンに Cross-region Load Balancer を作成

```bash:bash
# Cross-region Load Balancer を作成します
az network cross-region-lb create \
  --name ${prefix} \
  --location $region1 \
  --resource-group ${prefix}-rg \
  --frontend-ip-name ${prefix}-fe \
  --backend-pool-name ${prefix}-be

# ロードバランサー規則を作成します
az network cross-region-lb rule create \
  --backend-port 80 \
  --frontend-port 80 \
  --lb-name ${prefix} \
  --name ${prefix}-rule-web \
  --protocol tcp \
  --resource-group ${prefix}-rg \
  --frontend-ip-name ${prefix}-fe \
  --backend-pool-name ${prefix}-be

# 東日本フロントエンドをリージョン間ロードバランサーのバックエンドプールに追加します
az network cross-region-lb address-pool address add \
  --frontend-ip-address $(az network lb frontend-ip show \
  --lb-name ${prefix}-jpLB \
  --name loadBalancerFrontEnd \
  --resource-group ${prefix}-rg \
  --query id \
  --output tsv) \
  --lb-name ${prefix} \
  --name ${prefix}-jp \
  --pool-name ${prefix}-be \
  --resource-group ${prefix}-rg

# 東アジアフロントエンドをリージョン間ロードバランサーのバックエンドプールに追加します
az network cross-region-lb address-pool address add \
  --frontend-ip-address $(az network lb frontend-ip show \
  --lb-name ${prefix}-hkLB \
  --name loadBalancerFrontEnd \
  --resource-group ${prefix}-rg \
  --query id \
  --output tsv) \
  --lb-name ${prefix} \
  --name ${prefix}-hk \
  --pool-name ${prefix}-be \
  --resource-group ${prefix}-rg

# Cross-region LB の IP アドレスを取得します
vmcr=$(az network public-ip show \
  --resource-group ${prefix}-rg \
  --name PublicIP${prefix} \
  --query "ipAddress" \
  --output tsv)

# Cross-region LB の IP アドレスにアクセスします
curl -s $vmcr
```

何回かアクセスすると以下のように東日本リージョンのホスト名を含んだレスポンスだけを返します。これは超低遅延を使用した、最も近い Azure リージョンへのリージョン間の負荷分散となるためです。

```bash:bash
$ curl -s $vmcr
Hello World from host mnrcr6b95000003 !
$ curl -s $vmcr
Hello World from host mnrcr6b95000001 !
$ curl -s $vmcr
Hello World from host mnrcr6b95000003 !
$ curl -s $vmcr
Hello World from host mnrcr6b95000001 !
```

あえて東日本リージョンフロントエンドをリージョン間ロードバランサーのバックエンドプールから削除して、東アジアリージョンにアクセスできるか試してみます。

```bash:bash
# 東日本リージョンフロントエンドをリージョン間ロードバランサーのバックエンドプールから削除します
az network cross-region-lb address-pool address remove \
  --resource-group ${prefix}-rg \
  --lb-name ${prefix} \
  --pool-name ${prefix}-be \
  --name ${prefix}-jp
```

何回かアクセスすると以下のように東アジアリージョンのホスト名を含んだレスポンスを順番に返します。

```bash:bash
$ curl -s $vmcr
Hello World from host mnrcr5c1f000000 !
$ curl -s $vmcr
Hello World from host mnrcr5c1f000001 !
$ curl -s $vmcr
Hello World from host mnrcr5c1f000000 !
$ curl -s $vmcr
Hello World from host mnrcr5c1f000001 !
```

## 検証環境の削除

```bash:bash
# リソースグループを削除します
az group delete \
  --name ${prefix}-rg \
  --yes
```

## 参考

https://docs.microsoft.com/ja-jp/azure/load-balancer/cross-region-overview

https://docs.microsoft.com/ja-jp/azure/load-balancer/tutorial-cross-region-cli

https://docs.microsoft.com/ja-jp/azure/virtual-machine-scale-sets/quick-create-cli