Terraform 未対応の Azure リソースも Terraform で管理できる AzAPI を試してみた

## 背景と目的

Terraform で IaC 便利ですよね。使い込んでいくと、あれ？ Terraform に対応する resource が無い！なんて事があったりします。今までは Azure CLI や Azure REST API でカバーしていましたが、これからは Terraform の AzAPI resource で対応出来そうです。という事で今回は、リソースグループと仮想ネットワークを作成する例を Azure CLI と Terraform の通常版で試しつつ、最後に Terraform の AzAPI 組み込み版を試してみました。

## 前提条件

コマンドの実施環境は、Mac + Azure CLI です。

```bash:bash
$ sw_vers
ProductName:    macOS
ProductVersion: 12.3.1
BuildVersion:   21E258

$ az version
{
  "azure-cli": "2.35.0",
  "azure-cli-core": "2.35.0",
  "azure-cli-telemetry": "1.0.6",
  "extensions": {}
}

$ terraform -v
Terraform v1.1.8
on darwin_amd64
```

## Azure CLI でリソースグループと仮想ネットワークを作成する例

```bash:bash
# リソースグループを作成します
az group create \
  --name test-rg \
  --location japaneast

# 仮想ネットワークを作成します
az network vnet create \
  --resource-group test-rg \
  --name test-vnet \
  --address-prefixes 10.0.0.0/16

# 仮想ネットワークを更新します
az network vnet update \
  --resource-group test-rg \
  --name test-vnet \
  --address-prefixes 172.16.0.0/16

# リソースグループを削除します
az group delete \
  --name test-rg
```

## Terraform でリソースグループと仮想ネットワークを作成する例

```bash:bash
# Terraform コードを作成します
cat <<EOF > main.tf
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
    }
  }
}

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "test-rg" {
  name     = "test-rg"
  location = "japaneast"
}

resource "azurerm_virtual_network" "test-vnet" {
  name                = "test-vnet"
  location            = azurerm_resource_group.test-rg.location
  resource_group_name = azurerm_resource_group.test-rg.name
  address_space       = ["10.0.0.0/16"]
}
EOF

# 初期化します
terraform init

# 実行プランを確認します
terraform plan

# Terraform を実行します
terraform apply -auto-approve

# 仮想ネットワークのアドレス空間を変更します
gsed -i 's/10.0.0.0/172.16.0.0/' main.tf 

# 実行プランを確認します
terraform plan

# Terraform を実行します
terraform apply -auto-approve

# 作成したリソースを削除します
terraform destroy
```

## AzAPI を組み込んだ Terraform でリソースグループと仮想ネットワークを作成する例

```bash:bash
# Terraform コードを作成します
cat <<EOF > main.tf
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
    }
    azapi = {
      source  = "azure/azapi"
    }
  }
}

provider "azurerm" {
  features {}
}

provider "azapi" {
}

resource "azurerm_resource_group" "test-rg" {
  name     = "test-rg"
  location = "japaneast"
}

resource "azapi_resource" "test-vnet" {
  type      = "Microsoft.Network/virtualNetworks@2021-05-01"
  name      = "test-vnet"
  parent_id = azurerm_resource_group.test-rg.id
  location  = azurerm_resource_group.test-rg.location

  body = jsonencode({
    properties = {
      "addressSpace": {
        "addressPrefixes": [
          "10.0.0.0/16"
        ]
      }
    }
  })
}
EOF

# 初期化します
terraform init

# 実行プランを確認します
terraform plan

# Terraform を実行します
terraform apply -auto-approve

# 仮想ネットワークのアドレス空間を変更します
gsed -i 's/10.0.0.0/172.16.0.0/' main.tf 

# 実行プランを確認します
terraform plan

# Terraform を実行します
terraform apply -auto-approve

# 作成したリソースを削除します
terraform destroy
```

## 参考

<https://docs.microsoft.com/en-us/azure/developer/terraform/overview-azapi-provider>

<https://docs.microsoft.com/en-us/azure/developer/terraform/get-started-azapi-resource>

<https://techcommunity.microsoft.com/t5/azure-tools-blog/announcing-azure-terrafy-and-azapi-terraform-provider-previews/ba-p/3270937>

<https://docs.microsoft.com/ja-jp/rest/api/virtualnetwork/virtual-networks/create-or-update>