「世の中には難しいことが多い!」と感じることが多い私が、様々な用語を、初学者向けにわかりやすく全力で解説します。
解説する用語
Terraformのモジュールについて解説をします。モジュールはTerraformを学ぶ上で、ぶつかる壁の1つだと思います。本記事では具体的なソースコードをもとに解説をしていきますのでぜひ読んでみてください。
module(モジュール)とは
インフラ環境を構築する際には、テスト用の環境と本番環境など、同じ構成の複数の環境を作成することが多いです。
テスト用の環境と本番環境は同じような構成の環境のため、Terraformのソースコードも同じソースコードを2つ書くことになります。しかし、これでは変更が加わった際に2つのソースコードを修正しなければならないためめんどくさいです。。
そこで、moduleを使用することで、Terraformのソースコードを共通部品としてまとめることが出来ます。
以下の例だと、module.tfに本番環境とテスト環境で共通の内容を記載します。test_main.tfではテスト環境で使用する値を渡してmodule.tfを実行します。これにより、渡した値に応じたリソースを作成することが出来ます。variable.tfではmoduleで使用する変数を定義します。
本番環境ではprd_main.tfというファイルを用意し、test_main.tfで使用したmodule.tfを実行します。このように共通処理をmodule.tfに記載することで重複する行を省き、メンテナンスがしやすいソースコードを書くことが出来ます。
なかなかイメージが付きにくいかと思いますので、具体的なソースコードを用いて説明をします。
moduleを使ったフォルダ構成とソースコード
本記事の例としてterraformで作成するリソース
terraformのモジュールを使用して、Google CloudのCompute EngineのVMインスタンスを作成するシンプルなコードを書いてみます。
Google Cloudになじみのない方は「仮想マシンを作成するんだな~」くらいで理解をしていただけばOKです。
moduleの基本的な構文
モジュールの基本的な構文は以下です。
module "モジュールとして実行するリソースの名前(好きな名前でよい)" {
# moduleの呼び出し
source = "(相対パスでモジュールを定義したフォルダのパスを記載する)"
# moduleに受け渡す値
パラメータ名 = "パラメータの値"
}
4行目のsourceにはモジュールを格納しているフォルダまでのパスを記載します。こちらに記載したフォルダ配下のモジュールがすべて実行されます。
7行目には、パラメータ名とパラメータの値を記載しています。これによって、モジュールへ値を受け渡すことが出来ます。
moduleを使用したおすすめのフォルダ構成
moduleを使用する場合は以下のようなフォルダ構成がおすすめです。
terraform/
└─ environments/ ←モジュールを実行するコードを格納するフォルダ
└─ dev/
└─ compute_engine.tf
└─ prd/
└─ compute_engine.tf
└─ modules/ ←モジュールを格納するフォルダ
└─ compute_engine/
└─ variable.tf
└─ main.tf
environments/devフォルダにはモジュールを実行するためのファイルを格納します。今回はCompute EngineのVMインスタンスを作成するため、compute_engine.tfというファイルを作成し、そこにモジュールを実行するような内容を記載していきます。本番環境を追加する場合はenvironments/prdなどのフォルダを追加し、prdフォルダ配下に本番環境用のソースコードを追加していきます。
modulesフォルダには、モジュールを追加していきます。今回はcompute_engineというフォルダを作成し、そこにCompute EngineのVMインスタンスを作成するためのモジュールを作成します。
モジュールを使用した例
具体的なソースコードの中身を解説していきます。
dev/compute_engine.tf
dev配下のcompute_engine.tfではモジュールを実行するためのソースコードを記載します。
# compute_engine.tf
module "vm_instance" {
source = "../../../modules/compute_engine" # moduleの呼び出し
project_id = "test-project" # プロジェクト名
zone = "asia-northeast1-a" # リージョンとゾーン
machine_type = "f1-micro" # 仮想マシンの種類
image = "debian-cloud/debian-11" # オペレーティングシステムのイメージ
boot_disk_size_gb = 10 # ディスクのサイズ (GB)
}
5行目のsourceには実行するモジュールが格納されているフォルダを相対パスで記載します。今回はmodules/compute_engineのモジュールを実行します。
7行目以降にはモジュールに受け渡す値を記載しています。変数名はvariable.tfに記載されている変数名と同じにする必要があります。モジュールはこちらの値をもとにリソースを作成していきます。
modules/compute_engine/main.tf
main.tfにはモジュールを記載していきます。モジュールと言っても実行するリソースを記載していくだけです。
# main.tf
resource "google_compute_instance" "vm_instance" {
name = "test-instance"
machine_type = var.machine_type
zone = var.zone
boot_disk {
initialize_params {
image = var.image
}
size_gb = var.boot_disk_size_gb
}
network_interface {
network = "default"
}
}
こちらはTerraformのresourceの書き方と同じです。今回はGoogleCloudの仮想マシンを作成するようなコードを記載しています。var.変数名と記載することで、dev/compute_engine.tfから受け渡された値を使用しています。
modules/compute_engine/variable.tf
variable.tfでは、dev/compute_engine.tfから受け渡される変数を定義しています。
# variable.tf
variable "project_id" {
type = string
}
variable "zone" {
type = string
}
variable "machine_type" {
type = string
}
variable "image" {
type = string
}
variable "boot_disk_size_gb" {
type = number
}
このように定義をしておくことで、dev/compute_engine.tf受け渡された値をmain.tfで使用することが出来ます。
Terraformを実行する
モジュールを実行するためのソースコードがあるフォルダ配下に移動し、terraformを実行していくことで、モジュールを使用してリソースが作成されます。「terraform init」、「terraform plan」、「terraform apply」と実行していく感じですね。
今回の例では、environments/devフォルダ配下に移動し、terraformを実行します。
例として作成したファイルの関係性
このようにモジュールを使用することで、modules/compute_engine/main.tfに記載した内容をテスト環境や本番環境ごとに記載しなくても良くなります。
今回作成したファイルの関係性を図で表してみます。
main.tfには共通処理をモジュールとして記載しています。
variable.tfにはモジュールで使用する変数を定義しました。
compute_engine.tfを実行することで、main.tfに値を渡して実行します。
まとめ
- Terraformのモジュールを使用すると共通部分を部品としてまとめることが出来ます
- 部品としてまとめることで、毎回同じコードを各手間を省くことが出来ます
- ソースコードの可読性やメンテナンス性を高めることにもなります
参考
Udemyの以下の講座を参考にさせていただきました。複数の講座を視聴しましたが、個人的にはこちらの講座が一番分かりやすかったです。講座ではTerraformについて、初学者にも分かりやすく説明してくれているので、Terraformを学びたい方は視聴してみてください。
Infrastructure as Code のツールとしてよく使われる Terraform を、基本的な実装方法やコマンドから、モジュール化・複数環境の管理といった実践的な内容まで、AWS でのハンズオンでしっかり学びましょう!