📌

Terraformを本気で使う。Azureで【既存リソースのTF化編】

2024/10/21に公開

はじめに

前回までの記事では主にTerraform Cloudの使い方について試用記を書きました。

https://zenn.dev/yotan/articles/09ddfbf6db24d1

https://zenn.dev/yotan/articles/f67037e76526e3

今回は既存のAzure上のリソースをエクスポートしてTFファイルを作成していきたいと思います。

Azure Export for Terraform

このツールですね。

https://github.com/Azure/aztfexport

MS公式ドキュメントは以下です。

Azure Export for Terraform の概要

こちらは、すでにAzureサブスクリプション上に作成済のリソースを単独リソース・リソースグループ・サブスクリプション単位でエクスポートできるツールです。

本記事執筆時点ではCLIでの提供になっていますが、近日中にAzureポータルに組み込まれたものがPreviewで利用開始されそうですね。

https://x.com/AzureTerraform/status/1846624752128946530

まあ、とりあえずCLI版のaztfexportを使っていきます。

Azureリソースの準備

普通の仮想ネットワークや、仮想マシンでは普通過ぎて面白くないので以前作成したContainer Apps上にMinecraft Java Editionのコンテナを立ち上げる環境一式を先ずはデプロイします。

こちらはBicepで書かれています。

https://github.com/katakura/azure-container-app-minecraft

詳しいデプロイ方法はリポジトリ内のREADMEを読んでいただくとして、一式をデプロイすると以下のリソースがリソースグループ内に作成されます。

  • リソースグループ (rg-minecraft-java-server)
    • Virtual Network (+ subnet)
    • Container Apps Environment
    • Container App (Minecraft Container)
    • Storage Account (+ Storage container)
    • Log Analytics

img

img
Container Appが払い出したFQDNを設定

img
ちゃんと動きました

aztfexportのインストール

私の場合はUbuntu 22.04 LTSなので、ドキュメントを参考に以下のコマンドでインストールしました。

sudo su
ver=22.04
apt-add-repository https://packages.microsoft.com/ubuntu/${ver}/prod
apt-get install aztfexport

本記事執筆時点では以下のVersionが入りました。

$ aztfexport --version
aztfexport version v0.15.0(f1f6cce)

aztfexportの実行

適当なディレクトリを作成して、その配下で作業します。

流れとしては以下の感じかと。

  • Azureにログイン、サブスクリプション設定
  • aztfexport起動
    • export不要なリソースの除外設定
    • 必要なリソースの名前決定
    • tfファイル出力
  • tfファイルの校正

完全自動ツールではないです。清書されたARM TemplateやBicepファイルから変換できれば、他リソースのID参照やリソース命名もきれいに引き継げるでしょうが、そこまでパーフェクトではないです。

Azureにログイン、サブスクリプション設定

Azureにログインします。ついでに適当なディレクトリに移動もしておきます。

mkdir ./tfexport
cd ./tfexport
az account clear
az login -t <テナント名>
az account set -s <サブスクリプション名 or ID>

リソースグループ内のリソース一覧を念のため確認しておきます。

$ az resource list -g rg-minecraft-java-server -o table
Name                      ResourceGroup             Location    Type                                      Status
------------------------  ------------------------  ----------  ----------------------------------------  --------
vnet-minecraft            rg-minecraft-java-server  japaneast   Microsoft.Network/virtualNetworks
log-minecraft             rg-minecraft-java-server  japaneast   Microsoft.OperationalInsights/workspaces
stminecraftz6g4sa4sns7fw  rg-minecraft-java-server  japaneast   Microsoft.Storage/storageAccounts
acaenv-minecraft          rg-minecraft-java-server  japaneast   Microsoft.App/managedEnvironments
minecraft                 rg-minecraft-java-server  japaneast   Microsoft.App/containerApps

aztfexport起動

前準備

記事を書く前に何度か動かしたのですが、aztfexport内でAzureリソースのチェックを行う中で、ストレージアカウントのデータプレーンに対してもアクセスしているようなので、Firewall設定を追加しました。

今回のストレージアカウントはサービスエンドポイントで特定の仮想ネットワークからのみ許可していたのですが、aztfexportを実行するPCのIPアドレスを一時的に追加しています。

img

今回はリソースグループ内のリソースすべてをtf化するので、以下のコマンドを使用します。

aztfexport rg rg-minecraft-java-server

起動後の画面で「?」を押して、ヘルプの詳細を表示しました。

img

  • カーソル移動
    • ↑/k : up
    • ↓/j : down
    • →/l/pgdn : next page
    • ←/h/pgup : prev page
    • g/home : go to start
    • G/end : go to end
  • / : 一覧表示を任意の文字列が含まれるものでフィルタ表示
  • delete : (skip)フラグを付けてExxportしない
  • e : 変換エラー発生時の詳細表示
  • r : 変換エラー発生時の推奨事項表示
  • w : Export
  • s : 作業途中の状態を保存
  • q : 終了
  • ? : ヘルプを閉じる

不要リソースの除外設定

ざっと一覧を見ると、Log Analyticsの作成時に自動で作られる Microsoft.OperationalInsights/workspaces/tables の大量リソースは自動で「(skip)」が設定されていますのでこのままで。

Microsoft.OperationalInsights/workspaces/savedSearches はこのままではtf化されてしまいますので、「delete」ボタンでスキップ指定をします。この際に「/」のフィルタコマンドで「savedSearches」で絞込表示を行うと指定しやすいです。

img

最後に「ESC」を押してフィルタ表示状態を解除します。

今回のリソース類でいうと、これくらい除外すれば大丈夫っぽいです。

リソース名のマッピング

Terraformのtfファイル内でリソースの可読性を良くするために、規定でつけられているリソース名を用途毎に変更しましょう。

具体的にはリソースグループ名は「azurerm_resource_group.res-0」となっていますが、これを「azurerm_resource_group.main」とかに変更します。

私はまだこの命名をどうするのがベストなのか不勉強なのですが、リソースプロバイダが異なれば同じ名前を付けても良いとのことなので、基本「main」にします。

重複する場合にはそれっぽい名前を付けていきましょう。

作業途中で中断する場合は「s」を押すと、カレントディレクトリに aztfexportResourceMapping.json というファイルが作成されて現在の状態が保存されるので、後日続きを・・・とかも楽ちんですね。

ただし、手動で追加したスキップ指定は保持されないみたいです。(今のVersionでは)

エクスポート

最後に「w」を押してエクスポートします。

無事ノーエラーの場合はカレントディレクトリに「main.tf」が出力されます。

もしエラー発生の場合は「e」や「r」コマンドでエラー詳細の確認を行うことになります。

$ ls -l
total 152
-rw-r--r-- 1 yotan yotan   3585 Oct 21 12:16 aztfexportResourceMapping.json
-rw-r--r-- 1 yotan yotan 111247 Oct 21 12:16 aztfexportSkippedResources.txt
-rw------- 1 yotan yotan   4057 Oct 21 12:16 main.tf
-rw-r--r-- 1 yotan yotan    296 Oct 21 10:40 provider.tf
-rw-r--r-- 1 yotan yotan    146 Oct 21 10:40 terraform.tf
-rw-rw-r-- 1 yotan yotan  24167 Oct 21 12:16 terraform.tfstate

tfファイルの校正

エクスポートされたmain.tfは以下に置きました。

https://github.com/katakura/azure-container-app-minecraft/blob/main/exported/tf-from-aztfexport/before/main-before.tf

以下の対応が必要でしょう。

  • リソース間で参照しているもの(リソースIDなど)の修正(これによりdepends_onも不要となる)
  • パラメータ化が必要なものはvariables化
  • ストレージアカウント名などの文字列をユニーク化
  • リソースグループ内にリソース設定が無い診断設定(azurerm_monitor_diagnostic_setting)の追加

最初のリソースIDの参照などは、AzureポータルのエクスポートでARM Templateに出力する際にはresourceId()でそれっぽく変換してくれたのですが、aztfexportではリソースIDが思い切り入っていますね。

https://github.com/katakura/azure-container-app-minecraft/blob/main/exported/arm-from-portal/mainTemplate.json#L185-L190

修正したファイルはこちらです。

https://github.com/katakura/azure-container-app-minecraft/blob/main/exported/tf-from-aztfexport/after/main.tf

Bicep版と合わせて、パラメータ類はしっかり元の形状まで直すべきなのですが、とりあえずリソースグループ、リージョン、ストレージアカウント名のユニーク化だけ対応しました。

手動で修正した差分を見ると、結構修正が必要でしたね。。。

https://github.com/katakura/azure-container-app-minecraft/commit/a99f743ce6c12ac1ed7d9bd3730d1526d71e290c

デプロイ

main.tfがあるディレクトリに前回までの記事で作成したproviders.tfをコピーしてきてワークスペース名だけ修正しました。

providers.tf
terraform {
  cloud {
    organization = "組織名"
    hostname     = "app.terraform.io"
    workspaces {
      name = "ワークスペース名"
    }
  }
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "=4.1.0"
    }
  }
}
provider "azurerm" {
  features {}
}

あとは、plan, apply実行して試しますが、variablesのresource_group_nameは別の名前にしておきます。

terraform plan
terraform apply

img
無事完成

img
ちゃんと遊べました

おわりに

以下徒然と

  • AzureポータルからARM Templateのデプロイと同様ではあるが、一度Azure管理下になったリソースのプロパティから全てを戻せるわけではない
    • パラメータにすべきものとか
    • リソース間参照しているリソースIDの扱いとか
    • そもそもエクスポートできないシークレット値とか
  • できれば手動で作成した「ちゃんとした」Bicep, ARM Templateから直接Terraformに変換したい
  • 結局自身で修正する範囲が多いため、勘所をつかんでいないと大変だとおもう
    • ただし、ヘルパーツールとして考えるととても便利ではある
  • AzureポータルからTerraformにエクスポートする機能が追加される際にどれだけ機能が増えているのか期待!

後は、私が「Azure」以前にTerraformの文法とかお作法をもっとしっかりやらないとという事が永遠の課題としてありそうです。

以上、参考になれば幸いです。

Discussion