terraform-review について
インフラ変更のプルリクエストをレビューしたり、既存コードを監査したりするエンジニア向けのTerraformレビュースキルです。8カテゴリのチェックリストを適用し、ファイルと行を示した指摘と、Approved、Needs Changes、Blockedの判定を出します。
主な機能
- 018カテゴリのレビューチェックリスト
- 02セキュリティと状態管理の確認
- 03ブロッカーと提案の区別
- 04ファイル・行単位の指摘
- 05構造化された判定とレポート
活用シーン
- 01Terraformのプルリクエストのレビュー
- 02マージ前のインフラ変更の検証
- 03PR作成前のセルフレビュー
- 04既存Terraformコードの監査
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ c0x12c/ ai-toolkit --skill terraform-reviewインストール後、Claude Code で/terraform-reviewを入力して読み込まれたか確認します。
詳細
Terraform レビュー
Terraform の変更を 8 つのカテゴリのチェックリストでレビューします。「承認済み」「要修正」「ブロック」の判定を出します。
使用する場面
- Terraform のプルリクエストをレビューするとき
- インフラストラクチャの変更をマージ前に検証するとき
- PR を作成する前にセルフレビューするとき
- 既存の Terraform コードを監査するとき
プロセス
1. 構成
- ファイルが標準的なレイアウトに従っている:
live/、modules/、envs/ - モジュール内では、1 ファイルにつき 1 つのリソースになっている
-
terraform.tfにバックエンドとプロバイダーの設定がある -
variables.tf、outputs.tf、locals.tfが個別のファイルになっている - PR に
.terraform/や*.tfstate*が含まれていない
# CORRECT structure
terraform/
live/terraform.tf # backend + provider
live/variables.tf # inputs
live/locals.tf # computed values
live/outputs.tf # exports
modules/{service}/ # one resource per file
envs/{env}/ # per-environment config
# WRONG — everything in one file
terraform/main.tf # 500 lines of mixed resources
2. ステートの安全性
- 自動化で
terraform stateコマンドを使用していない - ステートが DynamoDB ロックを有効にした S3 に保存されている
- 重要なリソース(RDS、データを含む S3)に
prevent_destroyが設定されている -
terraform state rmの実行計画を文書化せずにリソースを削除していない - セキュリティグループと起動設定に
create_before_destroyが設定されている - 既存リソースの取り込みには Import ブロックを使用している(
terraform importCLI ではない)
# CORRECT — protect critical resources
resource "aws_db_instance" "main" {
lifecycle {
prevent_destroy = true
}
}
# CORRECT — zero-downtime SG updates
resource "aws_security_group" "app" {
name_prefix = "${local.name_prefix}-app-"
lifecycle {
create_before_destroy = true
}
}
3. セキュリティ
- git にコミットされた
.tfや.tfvarsにシークレットが含まれていない - 機密変数に
sensitive = trueが設定されている - S3 バケットでパブリックアクセスがブロックされている
- RDS/Redis がプライベートサブネット内にのみ配置されている
- セキュリティグループが最小権限の原則に従っている(ALB 以外で
0.0.0.0/0からのインバウンドを許可していない) - 暗号化が有効になっている(S3 SSE、RDS の暗号化、Redis の転送中および保存時の暗号化)
- IAM ポリシーが最小権限の原則に従っており、
*リソースに対する*アクションがない
# WRONG — overly permissive
resource "aws_security_group_rule" "bad" {
cidr_blocks = ["0.0.0.0/0"]
from_port = 0
to_port = 65535
}
# CORRECT — scoped to specific source
resource "aws_security_group_rule" "good" {
source_security_group_id = var.alb_security_group_id
from_port = 8080
to_port = 8080
}
4. 命名
- リソースで
local.name_prefixを使用している(パターン:{project}-{service}-{env}) - モジュール内のすべてのリソースで命名規則が統一されている
- タグに Project、Service、Environment、ManagedBy が含まれている
- 名前やアカウント ID がハードコードされていない
# CORRECT
locals {
name_prefix = "${var.project}-${var.service}-${var.env}"
}
# WRONG
resource "aws_s3_bucket" "assets" {
bucket = "my-bucket-prod" # hardcoded
}
5. モジュール
- モジュール内にプロバイダーブロックがない
- モジュールのソースでバージョンを固定している(
?ref=vX.Y.Z) - モジュール間に循環依存がない
- モジュールの出力で、利用側に必要なものだけを公開している
- モジュールに、必要なプロバイダーバージョンを指定した
versions.tfがある
# CORRECT — pinned version
module "rds" {
source = "git::https://github.com/{project}/terraform-modules.git//rds?ref=v1.2.0"
}
# WRONG — no version pin
module "rds" {
source = "git::https://github.com/{project}/terraform-modules.git//rds"
}
6. 変数
- すべての変数に
descriptionとtypeが設定されている - 機密変数に
sensitive = trueが設定されている - 重要な入力値(CIDR、名前、列挙値)に検証ブロックがある
- 使用されていない変数がない
- 開発環境に適したデフォルト値を設定し、環境ごとに上書きしている
# CORRECT
variable "instance_class" {
description = "RDS instance class"
type = string
default = "db.t3.micro"
validation {
condition = can(regex("^db\\.", var.instance_class))
error_message = "Must be a valid RDS instance class."
}
}
# WRONG — no description, no type
variable "instance_class" {}
7. プロバイダー
- プロバイダーのバージョンを
~>(悲観的制約)で固定している - Terraform 自体の
required_versionを指定している - プロバイダーの設定が
live/terraform.tfのみにあり、モジュール内にはない - プロバイダーレベルでデフォルトタグを設定している
8. CI/CD
- CI で
terraform fmt -checkを実行している - CI で
terraform validateを実行している - Plan の出力を PR のコメントとして投稿している
- Apply は main へのマージ時にのみ実行される
- ステートロックで同時実行される Apply を防いでいる
- シークレットをコミットせず、CI 環境から注入している
対話スタイル
- PR で変更されたすべての
.tfファイルを読み取ります - すべてのカテゴリを確認し、セクションを省略しません
- ブロッキングする問題(セキュリティ、ステートの安全性)と提案を分けて指摘します
- 指摘ごとに正確なファイル名と行番号を示します
ルール
- ブロッキングする問題:コード内のシークレット、ステートロックがない、
0.0.0.0/0からのインバウンド、暗号化の欠如 - 要修正:説明の欠如、バージョンの固定がない、命名規則の不統一
- 提案:コードスタイル、任意の検証、ドキュメント
出力
次のような構造化されたレビューを作成します。
## Terraform Review: {PR title}
### Verdict: Approved | Needs Changes | Blocked
### Findings
#### Blocked (if any)
- [ ] **[Security]** Secrets found in terraform.tfvars — file:line
#### Needs Changes (if any)
- [ ] **[Naming]** Hardcoded bucket name in s3.tf:12
- [ ] **[Modules]** Missing version pin on RDS module
#### Suggestions (if any)
- **[Variables]** Consider adding validation on `instance_class`
### Checklist Summary
| Category | Status |
|-----------|--------|
| Structure | Pass |
| State | Pass |
| Security | Fail |
| Naming | Warn |
| Modules | Warn |
| Variables | Pass |
| Providers | Pass |
| CI/CD | Pass |
コメント
Markdown 対応