おはようございます、YASUです。
これまでTerraformの環境ごとの切り替え(dev/prod)まで扱いましたが、そこで1つ気になっていたことがあります。「dev用とprod用でtfvarsファイルは分けても、肝心のリソース定義(VPCやEC2などのコード自体)が、複数の環境フォルダで同じ内容を重複して書くことになるのでは?」という疑問です。今日は、その重複を解消する「モジュール化」について整理します。
結論
モジュールとは、Terraformのコードを「共通部品」としてひとまとめにし、複数の環境や複数のプロジェクトから使い回せるようにする仕組みです。同じVPCやEC2の定義を何度も書き写す必要がなくなり、修正も1箇所で済むようになります。
そもそも、なぜ重複が生まれるのか
以前扱った環境ごとのディレクトリ構成を思い出してみます。
environments/
dev/
main.tf
dev.tfvars
prod/
main.tf
prod.tfvars
この構成だと、dev/main.tfとprod/main.tfには、VPCやEC2といったリソースの定義そのものが、ほぼ同じ内容でそれぞれ書かれてしまいます。値(tfvars)は分けられても、コードの本体は複製されたままです。もし後からVPCの設定を1つ直したくなったら、devとprod、両方のファイルを手作業で直す必要があり、修正漏れの事故が起きやすくなります。
モジュールで共通部品化する
そこで、繰り返し使うリソース定義を「モジュール」という共通部品としてひとまとめにします。
modules/
vpc/
main.tf
variables.tf
outputs.tf
modules/vpcの中に、VPCを作るための共通コードを1回だけ書いておきます。
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
}
各環境から、モジュールを呼び出す
dev環境、prod環境それぞれのmain.tfでは、このモジュールを呼び出すだけで済むようになります。
# environments/dev/main.tf
module "vpc" {
source = "../../modules/vpc"
vpc_cidr = "10.0.0.0/16"
}
# environments/prod/main.tf
module "vpc" {
source = "../../modules/vpc"
vpc_cidr = "10.1.0.0/16"
}
sourceで、どこにあるモジュールを使うかを指定し、vpc_cidrのような値だけを、環境ごとに変えて渡しています。VPCそのものの作り方(コードの中身)は、modules/vpcの1箇所にしか存在しません。
モジュール化のメリット
- 修正が1箇所で済む:VPCの設定を直したくなったら、
modules/vpcだけ直せば、それを呼び出している全環境に反映される - 重複がなくなる:同じようなリソース定義を何度も書き写す必要がない
- 使い回しがきく:別の新しいプロジェクトでも、同じモジュールをそのまま呼び出せる
身近な例えで考えると
プログラミングにおける「関数」や「共通コンポーネント」と同じ発想です。同じ処理を何度も書く代わりに、1つの部品として定義しておき、必要な場所から呼び出して使う。Terraformのモジュールも、インフラの世界における「共通部品」という位置づけです。
まとめ
- 環境ごとにコードを複製すると、修正のたびに複数箇所を直す必要が出て事故の元になる
- モジュールとして共通部品化することで、コードの本体は1箇所にまとめられる
- 各環境からは
moduleブロックで呼び出し、値だけを環境ごとに渡す - プログラミングの「関数」と同じ発想で理解すると掴みやすい
dev/prodの切り替えを覚えた時点で感じていたモヤモヤが、モジュールの存在を知ったことでようやく解消しました。それでは、また明日!

コメント