はじめに
モジュール機能を使ったことがないので、やってみたいと思います。
ユースケースとしては同じリソースや構成がいくつも必要な際に有効な機能となります。
依存関係の無い単一のリソースであれば気にする必要はないですが、
依存関係が存在するとリソース同士が密結合となり運用のフェーズに入った際、修正や更改がしづらくなります。
難しいところですね。今回は理解することも兼ねてシンプルなVPC,サブネット,EC2の構成をモジュール化し、一回のapplyで作成できるよう進めてみたいと思います。
構成図
ファイル構成
tf_module/
├─ vpc/
│ ├─ main.tf
│ ├─ variables.tf
│ └─ outputs.tf
│
├─ ec2/
│ ├─ windows.tf(EC2)
│ ├─ variables.tf
│ └─ outputs.tf
│
├─ variables.tf
├─ provider.tf
└─ main.tf
tf_module/配下でmain.tf(ルートモジュール)をapplyすればVPCとEC2が一気にデプロイされます。
モジュール化における処理の流れ
モジュール化が処理される流れを見ていきましょう。
まずはルートモジュールから。
module "vpc" {
source = "./vpc"
vpc_cidr = var.vpc_cidr
subnet_cidr = var.subnet_cidr
az = var.az
}
module "ec2" {
source = "./ec2"
vpc_id = module.vpc.vpc_id
subnet_id = module.vpc.subnet_id
key_name = var.key_name
}
AWSコンソールでの操作がわかる場合それをイメージするとよいかもしれません。
VPCやサブネットを作成せずにEC2は起動できないかと思います。
terraformにおいてもそれはもちろん同じでモジュール化においても依存関係がないものから作成が行われます。
この順番はterraformが自動で解決してくれます。
上記のコードは上からVPC→EC2としていますが、これを逆にしてもVPC→EC2の順に作成が行われ、エラーになることはありません。
モジュール化をする上でVPC側で必要なのは以下のoutputです。
tf_module/vpc/outputs.tf
output "vpc_id" {
value = aws_vpc.main.id
}
output "subnet_id" {
value = aws_subnet.subnet.id
}
これをモジュールが参照し、EC2モジュールのvariables.tfに渡しています。
tf_module/ec2/variables.tf
variable "vpc_id" {
description = "VPC ID where EC2 will be deployed"
type = string
}
variable "subnet_id" {
description = "Subnet ID for EC2"
type = string
}
まとめ
まとめると以下の様になります。
VPC Module
┌──────────────────────────┐
│ output "vpc_id" │
└──────────┬───────────────┘
│ 値を渡す
▼
┌──────────────────────────┐
│ Root Module │
│ │
│ module "ec2" { │
│ vpc_id = module.vpc │
│ .vpc_id │
│ } │
└──────────┬───────────────┘
│ 値を渡す
▼
┌──────────────────────────┐
│ EC2 Module │
│ │
│ variable "vpc_id" │
│ resource aws_instance │
│ subnet_id = var.vpc_id │
└──────────────────────────┘
ソースコード
今回使用したコードは以下です。
https://github.com/Snooze2929/tf_module
お疲れ様でした。
