Azure Virtual Machine Scale Sets (VMSS) のスタンバイプールを Azure CLI で試してみた

Azure VMSS は簡単に負荷分散の構成を作成できるので便利です。今回は、あらかじめ割り当て解除済みの仮想マシンを用意しておく、スタンバイプールを試してみました。

## 検証用の VMSS を作成

```bash:bash
prefix=mnrvmss
region=japaneast

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

az vmss create \
  --resource-group ${prefix}-rg \
  --name ${prefix}-vmss \
  --image Ubuntu2204 \
  --vm-sku Standard_B1s \
  --storage-sku Standard_LRS \
  --upgrade-policy-mode automatic \
  --admin-username azureuser \
  --generate-ssh-keys
```

## VM に Nginx をインストール

```bash:bash
az vmss extension set \
  --publisher Microsoft.Azure.Extensions \
  --version 2.0 \
  --name CustomScript \
  --resource-group ${prefix}-rg \
  --vmss-name ${prefix}-vmss \
  --settings '{"fileUris":["https://raw.githubusercontent.com/Azure-Samples/compute-automation-configurations/master/automate_nginx.sh"],"commandToExecute":"./automate_nginx.sh"}'
```

## NSG でポート 80 を許可

```bash:bash
az network nsg rule create \
  --resource-group ${prefix}-rg \
  --name AllowHTTP \
  --nsg-name ${prefix}-vmssNSG \
  --priority 100 \
  --destination-port-ranges 80 \
  --access Allow \
  --protocol Tcp
```

## LB のパブリック IP にアクセスして動作確認

```bash:bash
pip=$(az network public-ip show \
  --resource-group ${prefix}-rg \
  --name ${prefix}-vmssLBPublicIP \
  --query "ipAddress" \
  --output tsv)

curl -s $pip
```

```txt
Hello from your web application!
```

## VM の一覧を確認

```bash:bash
az vm list \
  --resource-group ${prefix}-rg \
  --query "[].name" \
  --output tsv
```

```txt
mnrvmss-vmss_6335d3d3
mnrvmss-vmss_8aefe466
```

## 各 VM の index.html の内容を変更

```bash:bash
az vm run-command invoke \
  --resource-group ${prefix}-rg \
  --name mnrvmss-vmss_6335d3d3 \
  --command-id RunShellScript \
  --scripts "uname -n | sudo tee /var/www/html/index.html"

az vm run-command invoke \
  --resource-group ${prefix}-rg \
  --name mnrvmss-vmss_8aefe466 \
  --command-id RunShellScript \
  --scripts "uname -n | sudo tee /var/www/html/index.html"
```

## もう一度動作確認

```bash:bash
$ curl -s $pip
mnrvmss-RIZETV

$ curl -s $pip
mnrvmss-WHB4BE
```

## スタンバイプール用のサービスプリンシパルに権限を付与

```bash:bash
# Standby Pool Resource Provider に Virtual Machine Contributor 権限を付与
az role assignment create \
  --role "Virtual Machine Contributor" \
  --assignee "412d7969-a6e6-46f2-aaf7-ef3f6a9d517a" \
  --scope $(az group show \
    --name ${prefix}-rg \
    --query id \
    --output tsv)

# Standby Pool Resource Provider に Network Contributor 権限を付与
az role assignment create \
  --role "Network Contributor" \
  --assignee "412d7969-a6e6-46f2-aaf7-ef3f6a9d517a" \
  --scope $(az group show \
    --name ${prefix}-rg \
    --query id \
    --output tsv)

# Standby Pool Resource Provider に Managed Identity Operator 権限を付与
az role assignment create \
  --role "Managed Identity Operator" \
  --assignee "412d7969-a6e6-46f2-aaf7-ef3f6a9d517a" \
  --scope $(az group show \
    --name ${prefix}-rg \
    --query id \
    --output tsv)
```

![azure-vmss-standbypool-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/5d1b94c5-0e36-72d8-e694-bc50dce30651.png)


## スタンバイプールを作成

```bash:bash
az standby-vm-pool create \
  --resource-group ${prefix}-rg \
  --name ${prefix}-pool \
  --max-ready-capacity 5 \
  --min-ready-capacity 3 \
  --vm-state "Deallocated" \
  --vmss-id $(az vmss show \
    --resource-group ${prefix}-rg \
    --name ${prefix}-vmss \
    --query id \
    --output tsv)
```

## スタンバイプール作成後の VMSS インスタンス

![azure-vmss-standbypool-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/83de41d4-0074-d4d0-4ea0-e4cf4a7e4125.png)

## スタンバイプール作成後の VM 一覧

![azure-vmss-standbypool-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/b5b7eeff-a931-7bc8-abfa-c6aa12de404e.png)

## 後片付け

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

## 参考

https://techcommunity.microsoft.com/blog/azurecompute/general-availability-standby-pools-for-virtual-machine-scale-sets-with-flexible-/4287343

https://learn.microsoft.com/ja-jp/azure/virtual-machine-scale-sets/standby-pools-overview