Terraformを本気で使う。Azureで【既存リソースのTF化編】
はじめに
前回までの記事では主にTerraform Cloudの使い方について試用記を書きました。
今回は既存のAzure上のリソースをエクスポートしてTFファイルを作成していきたいと思います。
Azure Export for Terraform
このツールですね。
MS公式ドキュメントは以下です。
Azure Export for Terraform の概要
こちらは、すでにAzureサブスクリプション上に作成済のリソースを単独リソース・リソースグループ・サブスクリプション単位でエクスポートできるツールです。
本記事執筆時点ではCLIでの提供になっていますが、近日中にAzureポータルに組み込まれたものがPreviewで利用開始されそうですね。
まあ、とりあえずCLI版のaztfexportを使っていきます。
Azureリソースの準備
普通の仮想ネットワークや、仮想マシンでは普通過ぎて面白くないので以前作成したContainer Apps上にMinecraft Java Editionのコンテナを立ち上げる環境一式を先ずはデプロイします。
こちらはBicepで書かれています。
詳しいデプロイ方法はリポジトリ内のREADMEを読んでいただくとして、一式をデプロイすると以下のリソースがリソースグループ内に作成されます。
- リソースグループ (rg-minecraft-java-server)
- Virtual Network (+ subnet)
- Container Apps Environment
- Container App (Minecraft Container)
- Storage Account (+ Storage container)
- Log Analytics
Container Appが払い出したFQDNを設定
ちゃんと動きました
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アドレスを一時的に追加しています。
今回はリソースグループ内のリソースすべてをtf化するので、以下のコマンドを使用します。
aztfexport rg rg-minecraft-java-server
起動後の画面で「?」を押して、ヘルプの詳細を表示しました。
- カーソル移動
- ↑/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」で絞込表示を行うと指定しやすいです。
最後に「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は以下に置きました。
以下の対応が必要でしょう。
- リソース間で参照しているもの(リソースIDなど)の修正(これによりdepends_onも不要となる)
- パラメータ化が必要なものはvariables化
- ストレージアカウント名などの文字列をユニーク化
- リソースグループ内にリソース設定が無い診断設定(azurerm_monitor_diagnostic_setting)の追加
最初のリソースIDの参照などは、AzureポータルのエクスポートでARM Templateに出力する際にはresourceId()でそれっぽく変換してくれたのですが、aztfexportではリソースIDが思い切り入っていますね。
修正したファイルはこちらです。
Bicep版と合わせて、パラメータ類はしっかり元の形状まで直すべきなのですが、とりあえずリソースグループ、リージョン、ストレージアカウント名のユニーク化だけ対応しました。
手動で修正した差分を見ると、結構修正が必要でしたね。。。
デプロイ
main.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
無事完成
ちゃんと遊べました
おわりに
以下徒然と
- AzureポータルからARM Templateのデプロイと同様ではあるが、一度Azure管理下になったリソースのプロパティから全てを戻せるわけではない
- パラメータにすべきものとか
- リソース間参照しているリソースIDの扱いとか
- そもそもエクスポートできないシークレット値とか
- できれば手動で作成した「ちゃんとした」Bicep, ARM Templateから直接Terraformに変換したい
- 結局自身で修正する範囲が多いため、勘所をつかんでいないと大変だとおもう
- ただし、ヘルパーツールとして考えるととても便利ではある
- AzureポータルからTerraformにエクスポートする機能が追加される際にどれだけ機能が増えているのか期待!
後は、私が「Azure」以前にTerraformの文法とかお作法をもっとしっかりやらないとという事が永遠の課題としてありそうです。
以上、参考になれば幸いです。
Discussion