結論
去年はじめてTerraformを使ってからあまり違いを理解せずにいましたが、現在は
resource
はあるリソースを作成する、module
は複数のresource
を組み合わせてテンプレート化したものという感じで理解しました。module
を使うと複数のリソースを簡単に作れるイメージです。
以降では、30日後にglacier deep archiveへオブジェクトを移行するライフサイクルルールを持つS3バケットをTerraformで作る例をあげながら、module
とresource
の違いについて説明していこうと思います。
resourceとは
resourceを使う場合、ライフサイクルルールを適用したS3を作成するには以下のようなコードになります。
# S3バケット作成
resource "aws_s3_bucket" "example_bucket" {
bucket = "example-bucket-123"
}
# ライフサイクルルールの設定 (30日後にglacier deep archiveに移行)
resource "aws_s3_bucket_lifecycle_configuration" "example_lifecycle" {
bucket = aws_s3_bucket.example_bucket.id
rule {
id = "move-to-deep-archive"
status = "Enabled"
transition {
days = 30
storage_class = "DEEP_ARCHIVE"
}
}
}
まずはaws_s3_bucket
でバケット名を指定し、S3を作成します。
その後、aws_s3_bucket_lifecycle_configuration
にてライフサイクルルールを作成し、それをどのS3バケットに適用するかどうかを最初のbucket
で指定しています。
このように、S3バケット本体やそれに適用する設定をそれぞれ記述する必要があります。そのため、ライフサイクルルール以外にもバケットポリシーやイベント通知など、作成したいものが増えれば増えるほど書かなければいけないresource
の数が増えていきます。
一方で、どのリソースをどのように作成し、どれに適用したかを自分で考えながら書くことができるので間違いは起きにくい印象があります。
設定値のデフォルト値などを確認したい場合はresource
のドキュメントを見る必要があります。
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket
moduleとは
module
を使う場合、ライフサイクルルールを適用したS3を作成するには以下のようなコードになります。
# S3バケットのモジュールの呼び出し
module "s3_bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "4.1.2"
bucket = "example-bucket-123"
lifecycle_rules = [{
id = "move-to-deep-archive"
enabled = true
transition = [{
days = 30
storage_class = "DEEP_ARCHIVE"
}]
}]
}
ここではterraform-aws-modules/s3-bucket/aws
というモジュールを使ってS3バケットを作成しています。
https://registry.terraform.io/modules/terraform-aws-modules/s3-bucket/aws/latest
resource
を使った時と比べて、1つのmodule
内でS3バケットの作成もライフサイクルルールの作成も完結しています。
実はmodule
は複数のresource
をまとめたものであり、module
を呼び出す際に関数と同じように引数を渡してあげれば包括しているresource
を一気に作ってくれるようになっています。
例として、今回使ったモジュールのコードを見てみるとライフサイクルルールの作成は内部でresource
のaws_s3_bucket_lifecycle_configuration
を呼び出しています。
https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/blob/master/main.tf#L240
module
はresource
と違いシンプルにリソースを作成することができるというメリットがある一方、module
側が自動的にいくつかのresource
を作成するため、
-
module
内部での設定が原因でエラーが発生した場合、どのresource
で問題が起きたか特定するのに時間がかかる -
module
が内部でどのresource
を作成するかを完全に把握するのが難しい場合がある
といったデメリットがある印象です。
まとめ
resource
, module
それぞれメリット/デメリットがあるので場合によって上手に使い分けていきたいなと思いました。
最初にTerraformを触った時、このresource
とmodule
の違いがよくわからず、プロパティの調べ方に困った過去があるのでどなたかのご助力になるといいなと思います。