ルール
Do not create modules that only wrap a single resource; define resources directly in the caller when needed
(単一リソースを包むだけのモジュールは作らない。必要な場合は呼び出し元で直接リソースを定義する)
解説
特定の設定をまとめただけのリソースブロックをモジュールにしないようにします。
粒度が小さすぎるモジュールは保守性をかえって悪化させます。
4 件の記事
Do not create modules that only wrap a single resource; define resources directly in the caller when needed
(単一リソースを包むだけのモジュールは作らない。必要な場合は呼び出し元で直接リソースを定義する)
特定の設定をまとめただけのリソースブロックをモジュールにしないようにします。
粒度が小さすぎるモジュールは保守性をかえって悪化させます。
Group related resources logically and encapsulate by functional units like network foundation and data layer
(関連リソースを論理的にまとめ、ネットワーク基盤やデータ層のような機能単位でカプセル化する)
モジュールは用途に沿ったリソースをまとめられるように勤めます。variableブロックを用いた外部への依存およびoutputブロックを用いた外部への情報提供は少ないに越したことはありません。
# ネットワーク基盤を機能単位でまとめたモジュール
# modules/networking/main.tf
resource "aws_vpc" "main" {
}
resource "aws_subnet" "public" {
}
resource "aws_internet_gateway" "main" {
}
resource "aws_route_table" "public" {
}
Always expose reference values for resources within modules through outputs to make dependencies explicit
(モジュール内リソースの参照値は必ずoutputで公開し、依存関係を明示する)
あるモジュール内で作成されたリソースの値を他のモジュールやリソースで使用する際は、outputブロックを通じて利用させます。 言い方を変えると、dataブロックやARNのハードコーディングを用いるコーディングは、保守性を落とすため避けるべきです。
# outputで参照値を明示的に公開
# modules/networking/outputs.tf
output "vpc_id" {
description = "The ID of the VPC"
value = aws_vpc.main.id
}
Keep module hierarchy to 1-2 levels and maintain flat inheritance
(モジュール階層を1〜2段階に保ち、フラットな継承を維持する)
サブモジュールから別のサブモジュールを呼び出す構造は極力避けます。避けられない場合でも1度までとします。 コピペしたDRYではないベタ書きが増えるわけですが、Terraform用コードは結局それがバランスがいいようです。
# フラットなモジュール階層
# main.tf(ルートモジュール)
module "networking" {
source = "./modules/networking"
vpc_cidr = var.vpc_cidr
availability_zones = var.availability_zones
public_subnet_cidrs = var.public_subnet_cidrs
private_subnet_cidrs = var.private_subnet_cidrs
}
module "application" {
source = "./modules/application"
vpc_id = module.networking.vpc_id
private_subnet_ids = module.networking.private_subnet_ids
app_port = var.app_port
}
# modules/networking/ と modules/application/ は
# さらに他のモジュールを呼ばず、直接リソースを定義