Azure CLI で Azure Resource Manager (ARM) の デプロイ テンプレート を使用してみました

### 概要
「Infrastructer as Code」ということで、Terraform を用いて Azure環境上に Ubuntu のVMを作成した [この記事](https://qiita.com/turupon/items/c249680acea136aff42b)の Azure環境を対象に、リソースグループのテンプレートをエクスポートしておきます。「terraform destory」 でこの環境を削除した後、エクスポートしておいたテンプレートから同じ環境を再構築してみました。いくつかのエラーが出ましたが先人の知見を参考にし、Ubuntu の VM に SSH接続できることを確認しました。


### ローカル環境

- macOS Monterey 12.1
- python 3.8.3
- Azure CLI 2.28.0
- terraform v1.0.11

### 前提条件

1. Azure環境がすでに用意されていること（テナント/サブスクリプション）
2. ローカル環境に「azure cli」がインストールされていること
3. ローカル環境に「terraform」環境が構成されていること
4. TerraformでAzure上に環境構築するための[サービスプリンシパルが作成](https://qiita.com/turupon/items/5d024d43a60cd101be94)されており、Terraform のためのローカル環境変数が定義されていること
5. [この記事](https://qiita.com/turupon/items/c249680acea136aff42b)の環境がAzure上に構築されていること

---

## Azure環境の エクスポート と 削除

### リソースグループからテンプレートをエクスポートする

```
$ az group export --name rg_ituru_vm02 > exported_ubuntu.json
```

### Terraform で構築した環境の削除

```
$ terraform destroy
     :
    省略
     :
Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes
     :
    省略
     :

Destroy complete! Resources: 9 destroyed.
```

---

## テンプレートを利用したAzure環境のデプロイ

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

リソースグループにデプロイするために、事前にリソースグループを作成します

```
$ az group create --name rg_ituru_vm02 --location japaneast

{
  "id": "/subscriptions/xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz/resourceGroups/rg_ituru_vm02",
  "location": "japaneast",
  "managedBy": null,
  "name": "rg_ituru_vm02",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null,
  "type": "Microsoft.Resources/resourceGroups"
}
```

### リソースグループにデプロイ

```
$ az deployment group create --resource-group rg_ituru_vm02 --template-file exported_ubuntu.json

Please provide string value for 'networkInterfaces_nic_ituru_vm02_name' (? for help): nic_ituru_vm02
Please provide string value for 'networkSecurityGroups_nsg_ituru_vm02_name' (? for help): nsg_ituru_vm02
Please provide string value for 'publicIPAddresses_pip_ituru_vm02_name' (? for help): pip_ituru_vm02
Please provide string value for 'virtualMachines_vm_ituru_ubuntu_name' (? for help): vm_ituru_ubuntu
Please provide string value for 'virtualNetworks_vnet_ituru_vm02_name' (? for help): vnet_ituru_vm02
```

１回目の実行で以下のエラー

```
## エラーメッセージ
{"status":"Failed","error":{"code":"DeploymentFailed","message":"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.","details":[{"code":"BadRequest","message":"{\r\n  \"error\": {\r\n    \"code\": \"InvalidParameter\",\r\n    \"message\": \"Parameter 'osDisk.managedDisk.id' is not allowed.\",\r\n    \"target\": \"osDisk.managedDisk.id\"\r\n  }\r\n}"}]}}

## 対応策 : exported_ubuntu.json の 183行目 をコメントアウトする
          "osDisk": {
            "caching": "ReadWrite",
            "createOption": "FromImage",
            "deleteOption": "Detach",
            "diskSizeGB": 30,
            "managedDisk": {
              // "id": "[resourceId('Microsoft.Compute/disks', concat(parameters('virtualMachines_vm_ituru_ubuntu_name'), '_OsDisk_1_b5cc47db731b457599a6ab8fe41aa4df'))]",
              "storageAccountType": "Standard_LRS"
            },
            "name": "[concat(parameters('virtualMachines_vm_ituru_ubuntu_name'), '_OsDisk_1_b5cc47db731b457599a6ab8fe41aa4df')]",
            "osType": "Linux",
            "writeAcceleratorEnabled": false
          }
```

２回目の実行で以下のエラー

```
## エラーメッセージ
{"status":"Failed","error":{"code":"DeploymentFailed","message":"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.","details":[{"code":"BadRequest","message":"{\r\n  \"error\": {\r\n    \"code\": \"InvalidParameter\",\r\n    \"message\": \"The property 'requireGuestProvisionSignal' is not valid because the 'Microsoft.Compute/Agentless' feature is not enabled for this subscription.\",\r\n    \"target\": \"requireGuestProvisionSignal\"\r\n  }\r\n}"}]}}

## 対応策 : exported_ubuntu.json の 165行目 をコメントアウトする
        "osProfile": {
          "adminUsername": "nmcadmin",
          "allowExtensionOperations": true,
          "computerName": "ubuntu1804",
          "linuxConfiguration": {
            "disablePasswordAuthentication": true,
            "patchSettings": {
              "assessmentMode": "ImageDefault",
              "patchMode": "ImageDefault"
            },
            "provisionVMAgent": true,
            "ssh": {
              "publicKeys": [
                {
                  "keyData": "ssh-rsa xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx==\n",
                  "path": "/home/nmcadmin/.ssh/authorized_keys"
                }
              ]
            }
          },
          // "requireGuestProvisionSignal": true,
          "secrets": []
```

３回目の実行で無事成功！

---

## 実行後の確認

### 仮想マシン の確認

```
$ az vm list -g rg_ituru_vm02 -d --output table

Name             ResourceGroup    PowerState    PublicIps     Fqdns    Location    Zones
---------------  ---------------  ------------  ------------  -------  ----------  -------
vm_ituru_ubuntu  rg_ituru_vm02    VM running    20.89.16.235           japaneast
```

### ネットワークセキュリティグループ の確認

```
$ az network nsg rule list -g rg_ituru_vm02 --nsg-name nsg_ituru_vm02 -o table

Name    ResourceGroup    Priority    SourcePortRanges    SourceAddressPrefixes    SourceASG    Access    Protocol    Direction    DestinationPortRanges    DestinationAddressPrefixes    DestinationASG
------  ---------------  ----------  ------------------  -----------------------  -----------  --------  ----------  -----------  -----------------------  ----------------------------  ----------------
SSH     rg_ituru_vm02    1002        *                   153.134.22.135/32        None         Allow     Tcp         Inbound      22                       *                             None
```

---

### 仮想マシンへの接続

#### グローバルアドレスの取得

```
$ az vm list-ip-addresses --resource-group rg_ituru_vm02 --name vm_ituru_ubuntu --output table

VirtualMachine    PublicIPAddresses    PrivateIPAddresses
----------------  -------------------  --------------------
vm_ituru_ubuntu   20.89.16.235         10.0.1.4
```

## SSH接続

鍵は以前のものをそのまま利用可能

```
$ ssh -i vm_ubuntu.pem nmcadmin@20.89.16.235

The authenticity of host '20.89.16.235 (20.89.16.235)' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxl0.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '20.89.16.235' (ED25519) to the list of known hosts.
Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 5.4.0-1067-azure x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Mon Jan 24 15:20:09 UTC 2022

  System load:  0.17              Processes:           129
  Usage of /:   4.6% of 28.90GB   Users logged in:     0
  Memory usage: 1%                IP address for eth0: 10.0.1.4
  Swap usage:   0%

0 updates can be applied immediately.


The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

nmcadmin@ubuntu1804:~$ 
```

---

### 作成したリソースの削除

```
$ az group delete --name rg_ituru_vm02

Are you sure you want to perform this operation? (y/n): y
```

---

### まとめ

テンプレートからのデプロイ時のエラーメッセージの意味がわからず、、、、とりあえず、テンプレートからのデプロイ方法はどんなものかを知ることができました。

### 参考記事

以下の記事を参考にさせていただきました。感謝申し上げます。
[Deploying Infrastructure in Azure Using ARM Templates](https://thesleepyadmins.com/2021/11/28/deploying-infrastructure-in-azure-using-arm-templates/)