Azure Export for Terraformを使う

こちらを使うことで、Azure上に展開されているリソースをTerraformのコードとして出力することができるようになります。手っ取り早く手でリソースをポータル上で作成して、それをTerraformのコードとして落とすことで、簡単にリソースの管理ができるようになります。そこからモジュールに分けてリファクタリングすることで保守性も担保することができそうです。

以下のリンクを参考にしながら、1つのリソースグループ に入っているリソース群をTerraformのコードにしてみたいと思います。

https://learn.microsoft.com/ja-jp/azure/developer/terraform/azure-export-for-terraform/export-first-resources?tabs=azure-cli

まずはazログインをしてリソースにつなげていきます。

Terraformファイルは、カレントディレクトリに吐き出されるので、ディレクトリを移動しておきます。

cd /Users/takumi/Documents/src/private/terraform/out-rg-pwa

エクスポートを実行します。

aztfexport resource-group rg-pwa

以下のような画面になると思います。

この画面では、リソースが正しく認識されているかを確認するだけです。実際にエクスポートする場合はwを押します。

エクスポートすると、 これらファイルが出力されます。

takumi@ ~/Documents/src/private/terraform/out-rg-pwa$ tree
.
├── aztfexportResourceMapping.json
├── import.tf
├── main.tf
├── provider.tf
├── terraform.tf
└── terraform.tfstate

main.tfをマスクしてのせます。

resource "azurerm_resource_group" "res-0" {
  location = "eastasia"
  name     = "rg-pwa"
}
resource "azurerm_key_vault" "res-1" {
  location            = "eastasia"
  name                = "kv-xiao"
  resource_group_name = "rg-pwa"
  sku_name            = "standard"
  tenant_id           = "xxx"
}
resource "azurerm_key_vault_secret" "res-2" {
  key_vault_id = "xxx"
  name         = "sc-xiao-client-secret"
  tags = {
    file-encoding = "utf-8"
  }
  value = ""
  depends_on = [
    azurerm_key_vault.res-1,
  ]
}
resource "azurerm_key_vault_secret" "res-3" {
  key_vault_id = "xxx"
  name         = "sc-xiao-vm-ssh-key"
  tags = {
    file-encoding = "utf-8"
  }
  value = ""
  depends_on = [
    azurerm_key_vault.res-1,
  ]
}
resource "azurerm_static_site" "res-4" {
  app_settings = {
    B2C_CLIENT_ID = "xxx"
    B2C_SECRET    = "xxx"
  }
  location            = "eastasia"
  name                = "swa-pwa"
  resource_group_name = "rg-pwa"
}

ここからわかる情報としては、それぞれのリソースにはres-番号 というエイリアスが当てられていると言うところです。

参考にした公式のところでは、tf planして状態に差がないところまで確認していますが、今回は割愛しています。

別のオプションで出力範囲を絞る

クエリで絞る

以下のようにAzure Resource Graph クエリ構文を投げることもできるようです。これにより、リソース名にdevが含まれているものを抽出することができます。

aztfexport query -n "resourceGroup =~ 'rg-sample' and name contains 'dev'"

リソースのjsonファイルを削って出力する

以下のコマンドでリソースが一覧で出力されます。

aztfexport rg --generate-mapping-file --non-interactive myResourceGroup

結果の例は公式から引っ張ってきました。

{
	"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/virtualMachines/vm-MyResourceGroup/extensions/OmsAgentForLinux": {
		"resource_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/virtualMachines/vm-MyResourceGroup/extensions/OmsAgentForLinux",
		"resource_type": "azurerm_virtual_machine_extension",
		"resource_name": "res-0"
	},
	"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup": {
		"resource_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup",
		"resource_type": "azurerm_resource_group",
		"resource_name": "res-1"
	},
	"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/sshPublicKeys/vm-MyResourceGroup_key": {
		"resource_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/sshPublicKeys/vm-MyResourceGroup_key",
		"resource_type": "azurerm_ssh_public_key",
		"resource_name": "res-2"
	},
	"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/virtualMachines/vm-MyResourceGroup": {
		"resource_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/virtualMachines/vm-MyResourceGroup",
		"resource_type": "azurerm_linux_virtual_machine",
		"resource_name": "res-3"
	},
	"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Network/networkInterfaces/vm-myResourceGroup-vm-d146": {
		"resource_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Network/networkInterfaces/vm-myResourceGroup-vm-d146",
		"resource_type": "azurerm_network_interface",
		"resource_name": "res-4"
	}
}

上記でres-3とres-4は不要と判断した場合、以下のように作り直します。

{
	"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/virtualMachines/vm-MyResourceGroup/extensions/OmsAgentForLinux": {
		"resource_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/virtualMachines/vm-MyResourceGroup/extensions/OmsAgentForLinux",
		"resource_type": "azurerm_virtual_machine_extension",
		"resource_name": "res-0"
	},
	"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup": {
		"resource_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup",
		"resource_type": "azurerm_resource_group",
		"resource_name": "res-1"
	},
	"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/sshPublicKeys/vm-MyResourceGroup_key": {
		"resource_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/sshPublicKeys/vm-MyResourceGroup_key",
		"resource_type": "azurerm_ssh_public_key",
		"resource_name": "res-2"
	}
}

上記を使用してリソースをインポートすることができます。以下のコマンドで可能です。

aztfexport mapping-file <resource_mapping_file>

上記の<resource_mapping_file>がこのjsonファイル名になります。

このように一度手で作ってしまって、どのようなリソースが存在するのか、ポータル上でひとまとまりで生成されるリソースが何かを把握する事は非常にやりやすい方法だなと感じました。