はじめに
AWS Provider v6.25.0にて、CloudWatch Log Groupに deletion_protection_enabled 引数が追加されました。
これを受けて、terraform-aws-modules/lambda/aws モジュールに、この新しい引数を追加するプルリクエスト(PR)を送り、マージしてもらえたので、その過程を記録します。
ターゲット Issue / リクエスト内容
背景
CloudWatchロググループの削除保護機能がProvider側でサポートされたため、Lambdaモジュール経由でロググループを作成する際にも、この設定を制御したいというニーズがありました。
- 修正対象リポジトリ: terraform-aws-modules/terraform-aws-lambda
- 関連Issue: #735 (実装依頼)
- 参照Provider更新: AWS Provider v6.25.0 CHANGELOG
- PR: feat: Add deletion_protection_enabled argument for lambda log group
アプローチ:実装のポイント
後方互換性を損なわないよう以下の手順で実装しました。
1. 変数の定義 (variables.tf)
既存のログ関連変数の名称が cloudwatch_logs_* となっていたためそれに倣い、cloudwatch_logs_deletion_protection_enabled という名称で変数を追加しました。
デフォルト値を null に設定することで、明示的に指定しない限りProviderのデフォルト挙動(削除保護なし)を維持し、既存ユーザーに影響を与えないようにしました。
variable "cloudwatch_logs_deletion_protection_enabled" {
description = "Whether to enable deletion protection for the log group."
type = bool
default = null
}
2. リソースへの適用 (main.tf)
aws_cloudwatch_log_group.lambda リソースの引数に、定義した変数を紐付けました。
resource "aws_cloudwatch_log_group" "lambda" {
# ...(省略)...
log_group_class = var.cloudwatch_logs_log_group_class
deletion_protection_enabled = var.cloudwatch_logs_deletion_protection_enabled # 追加
tags = merge(var.tags, var.cloudwatch_logs_tags)
}
3. wrapperモジュールの同期 (wrappers/main.tf)
本リポジトリ特有の仕様である wrapper モジュール(モジュールをさらにラップして一括管理するための仕組み)にも変数を伝播させる必要があります。ここを修正しないとCIでエラーが発生するため、try 関数を用いて値を渡すように修正しました。
module "wrapper" {
# ...(省略)...
build_in_docker = try(each.value.build_in_docker, var.defaults.build_in_docker, false)
cloudwatch_logs_deletion_protection_enabled = try(each.value.cloudwatch_logs_deletion_protection_enabled, var.defaults.cloudwatch_logs_deletion_protection_enabled, null) # 追加
cloudwatch_logs_kms_key_id = try(each.value.cloudwatch_logs_kms_key_id, var.defaults.cloudwatch_logs_kms_key_id, null)
4. ドキュメントとExampleの更新
-
README.md: 変数の説明を追加しました。 -
examples/complete: このモジュールの全ての機能を盛り込んだテスト兼リファレンス用の構成案です。ここに実際に機能を有効化した設定例を追記し、動作確認ができる状態にしました。
module "lambda_function" {
source = "../../"
# ...(省略)...
cloudwatch_logs_log_group_class = "INFREQUENT_ACCESS"
cloudwatch_logs_deletion_protection_enabled = true # テスト用に有効化
role_path = "/tf-managed/"
}
つまずいたポイントと解決策
今回のPR作業で苦労したのは、コードそのものよりも開発環境とCIへの対応でした。
① 改行コード(CRLF, LF)
Windows環境で作業していたため、git add 時に意図せず多くのファイルで改行コードが変更されました。
-
解決策:
git config --global core.autocrlf inputを設定し、インデックス登録時にLFへ変換されるように修正。また、一度コミットをリセットし、必要なファイルのみを個別にgit addすることで、クリーンなDiffを実現しました。
② terraform fmt の実行
=(イコール)の縦の整列が崩れていると、レビュー前にCIで弾かれます。
-
解決策: 手動での修正ではなく、
terraform fmtを実行。
③ wrapperモジュールの同期
このリポジトリ特有の仕組みとして、メインモジュールをラップする wrappers ディレクトリが存在します。
メインの main.tf に引数を追加しただけでは、「wrapper側にもその引数を渡すように」とCI(pre-commit)がエラーを出しました。
-
解決策: CIのログに出力されたDiffを参考に、
wrappers/main.tfにもtry(...)関数を用いた新しい引数の受け渡しを追記しました。
結果
最終的に、30個の自動テスト(GitHub Actions / pre-commit)がすべて「Successful」となり、メンテナによるレビュー待ちの状態となりました。
その1週間後にTerraformメンテナであるantonbabenkoという方によって承認・マージされ、リリースバージョン 8.6.0 に取り込まれました。
おわりに
大規模なOSSへのコントリビューションは、コードを書くこと以上に「そのプロジェクトの作法やCI環境に合わせること」が重要だと学びました。
特に改行コードやフォーマットやテストの実施など、細部にまで気を配ることで、マージしてもらえるレベルのPRになるとわかりました。