【Azure】Terraformを用いてWeb Server（IIS、nginx）を作成する。

# 1. はじめに
### 1-1 ご挨拶
初めまして、井村と申します。
Terraformを用いてAzure VMを作成しました。
[「Azure の仮想マシンでインフラストラクチャ自動化ツールを使用する」](https://learn.microsoft.com/ja-jp/azure/virtual-machines/infrastructure-automation)に記述されている「Azure の仮想マシン (VM) を一貫した方法で大規模に作成および管理するには、一般的に、何らかの形で自動化することが必要です。」はとても共感できます。
そのため、インフラは「Terraform」、WindowsServerのIISは「Azure カスタム スクリプト拡張機能」、LinuxServerのnginxは「cloud-init」を用いて構築します。

### 1-2 対象読者
- Azureに興味がある
- Terraformに興味がある

### 1-3 構築するインフラ
下図の通り、フロントエンドサブネットにロードバランサー、バックエンドサブネットに仮想マシンを作成します。ロードバランサーのみにパブリックIPアドレスを付与します。

![00_system.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989465/820de695-3fb7-9262-8080-5f712a3dadf4.jpeg)


# 2. 構築
Terraform一式は[Github](https://github.com/hawk0722/Azure_Terraform_04_lb_vm)に格納しています。今回は仮想マシンのファイルのみ掲載いたします。

<details>
<summary>ディレクトリ構成</summary>
<pre>
<code>


```
.
├── env
│   └── dev
│       ├── cloud-init.yml
│       ├── main.tf
│       ├── outputs.tf
│       ├── provider.tf
│       ├── terraform.tfvars
│       └── variable.tf
└── modules
    ├── lbe
    │   ├── main.tf
    │   ├── outputs.tf
    │   └── variables.tf
    ├── nsg
    │   ├── main.tf
    │   ├── outputs.tf
    │   └── variables.tf
    ├── rg
    │   ├── main.tf
    │   ├── outputs.tf
    │   └── variables.tf
    ├── vm_linux
    │   ├── main.tf
    │   ├── outputs.tf
    │   └── variables.tf
    ├── vm_win
    │   ├── main.tf
    │   ├── outputs.tf
    │   └── variables.tf
    └── vnet
        ├── main.tf
        ├── outputs.tf
        └── variables.tf
      
```

</code>
</pre>
</details>


### 2-1 WindowsServerのmain.tf
利用するmain.tfは以下になります。

```terraform:main.tf
resource "azurerm_network_interface" "nic" {
  name                = "nic-win-${var.env}-${var.code}"
  location            = var.location
  resource_group_name = var.rg_name

  ip_configuration {
    name                          = "vm-win-${var.env}-${var.code}-ip-configuration"
    subnet_id                     = var.s_pri_id
    private_ip_address_allocation = "Dynamic"
  }
}

resource "azurerm_windows_virtual_machine" "vm" {
  name                = "vm-win-${var.env}-${var.code}"
  resource_group_name = var.rg_name
  location            = var.location
  size                = var.vm_win_size
  admin_username      = var.vm_win_login_username
  admin_password      = var.vm_win_login_password
  network_interface_ids = [
    azurerm_network_interface.nic.id,
  ]

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  source_image_reference {
    publisher = var.vm_win_img_publisher
    offer     = var.vm_win_img_offer
    sku       = var.vm_win_img_sku
    version   = var.vm_win_img_version
  }
}

resource "azurerm_virtual_machine_extension" "vm_extension" {
  name                 = "vm_extension_install_iis"
  virtual_machine_id   = azurerm_windows_virtual_machine.vm.id
  publisher            = "Microsoft.Compute"
  type                 = "CustomScriptExtension"
  type_handler_version = "1.10"

  settings = <<SETTINGS
 {
  "commandToExecute": "powershell -ExecutionPolicy Unrestricted Install-WindowsFeature -Name Web-Server -IncludeManagementTools -IncludeAllSubFeature"
 }
SETTINGS

}

```

「**azurerm_virtual_machine_extension**」ブロックでIISをインストールしています。


### 2-2 LinuxServerのmain.tf
利用するmain.tfは以下になります。

```terraform:main.tf
resource "azurerm_network_interface" "nic" {
  name                = "nic-linux-${var.env}-${var.code}"
  location            = var.location
  resource_group_name = var.rg_name

  ip_configuration {
    name                          = "vm-linux-${var.env}-${var.code}-ip-configuration"
    subnet_id                     = var.s_pri_id
    private_ip_address_allocation = "Dynamic"
  }
}

resource "azurerm_linux_virtual_machine" "vm" {
  name                = "vm-linux-${var.env}-${var.code}"
  resource_group_name = var.rg_name
  location            = var.location
  size                = var.vm_linux_size
  admin_username      = var.vm_linux_admin_username
  admin_password      = var.vm_linux_admin_password
  network_interface_ids = [
    azurerm_network_interface.nic.id,
  ]

  custom_data                     = filebase64("../../env/dev/cloud-init.yml")
  disable_password_authentication = false

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  source_image_reference {
    publisher = var.vm_linux_img_publisher
    offer     = var.vm_linux_img_offer
    sku       = var.vm_linux_img_sku
    version   = var.vm_linux_img_version
  }

}

```

「**custom_data = filebase64("../../env/dev/cloud-init.yml")**」で「cloud-init.yml」ファイルを呼出し、実行しています。

なお、「cloud-init.yml」は以下になります。

```yml:cloud-init.yml
#cloud-config
package_upgrade: true
packages:
  - nginx
```

### 2-3 実行
それでは構築を開始します。
devディレクトリに移動後、Terraformコマンドを実行してAzure上にインフラを構築します。

```bash:bash
terraform init
terraform plan
terraform apply
```

# 3. 動作確認
### 3-1 リソースの確認
Terraformコマンド実行後、下図のリソースが作成されます。

![01_rg2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989465/409a452c-c595-afa4-db97-bfff34145d16.png)

ロードバランサーのパブリックIPアドレスを確認します。
今回は「20.18.44.232」となります。

![02_pip-lbe2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989465/42361668-7fc0-9b71-f988-17528ac2a60d.png)


### 3-2 IISの確認
それではIISの動作確認となります。ローカル端末のWebブラウザに先ほど確認したIPアドレスを貼り付けます。
下図が表示されれば成功です。

![03_IIS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989465/c5c66483-0836-d571-f371-d30558895482.png)


### 3-3 nginxの確認
それではnginxの動作確認となります。ローカル端末のWebブラウザに先ほど確認したIPアドレスを貼り付けます。
下図が表示されれば成功です。

![04_nginx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989465/e2caee4f-6849-1b18-543f-129fbfdd06c2.png)


# 4. 終わりに
本記事を最後まで読んで頂きましてありがとうございます。
実際にロードバランサーの同一バックエンドプールに違うwebサーバを導入することはないでしょうが、無事に動いてよかったです。今回も正常動作するために、様々なドキュメントを読み漁って勉強になりました。

# 5. 参考記事
- [Azure の仮想マシンでインフラストラクチャ自動化ツールを使用する](https://learn.microsoft.com/ja-jp/azure/virtual-machines/infrastructure-automation)

- [クイック スタート: Terraform を使用して Windows VM を作成する](https://learn.microsoft.com/ja-jp/azure/virtual-machines/windows/quick-create-terraform)

- [NGINX をセキュリティで保護する cloud-init 構成を作成する](https://learn.microsoft.com/ja-jp/azure/virtual-machines/windows/quick-create-terraform)