課題
運用や開発をしていると、なぜもっと早いタイミングでこの問題に気づけなかったのかと苦労することはないでしょうか?
例えば、コンパイルエラーにはならずとも、特定の条件下ではエラーが発生し得る、障害につながる原因になり得るなどなど。
また、最近ではAIを使用したコードレビューは当たり前になってきていると思いますが、正しくAIを選択し、使用できているでしょうか?
正直私は特性までを理解して使用できていません。。
そこで今回は以下を目的とした検証を行いました。
- AIを用いて障害や問題の検知を楽にすること
- 適切なAIを選択すること
やったこと
- 簡単なシステムをCDKで構築
- 「CloudWatch(サブスクリプションフィルター)→Lambda→SNS」のシンプルな構成
- AIのレビューで使用するプロンプトを作成
- CDK資材とプロンプトを基に複数のAIにレビュー
- 今回は以下3つのAIエージェントを使用
- Kiro
- Amazon Q
- Copilot
- 今回は以下3つのAIエージェントを使用
- 出力結果の確認と比較
システムの構築
「CloudWatch(サブスクリプションフィルター)→Lambda→SNS」のシンプルな構成
サブスクリプションフィルターでLambdaをトリガーし、文言を整形後SNSにてUserへ通知を飛ばす想定
プロンプトの作成
障害や問題を検知することを目的としたプロンプトを作成しました。
(↓こんな感じ)
# AWS CDK 設計・実装レビュー依頼プロンプト
## あなたの役割
あなたは **AWSアーキテクト / SRE / セキュリティエンジニアの視点を併せ持つ専門家AI** です。
以下に提示する AWS CDK(Cloud Development Kit)資材一式を読み込み、
**設計・実装・運用・セキュリティ・コスト・可用性** の観点から、
障害や問題が発生し得る点を網羅的かつ批判的にレビューしてください。
---
## 対象物
- AWS CDK のソースコード(TypeScript / Python / 他)
- Stack 定義
- Construct 設計
- IAM ポリシー
- ネットワーク構成(VPC, Subnet, SG, NACL 等)
- マネージドサービス設定(ALB, ECS, EKS, Lambda, RDS, S3, etc)
- 環境分離(dev / stg / prod)
- パラメータ、Context、環境変数
---
## レビューの目的
以下を満たすか確認してください。
- 本番障害につながる設計・実装ミスがないか
- セキュリティ事故を引き起こす可能性がないか
- 将来的なスケールや運用で問題が顕在化しないか
- AWS ベストプラクティスや Well-Architected Framework に反していないか
- CDK 特有のアンチパターンが含まれていないか
---
## 必須レビュー観点
最低限、以下の観点を必ず含めてください。
### 1. 可用性・耐障害性
- Single AZ 構成になっていないか
- 冗長化不足、フェイルオーバー不能な設計
- Auto Scaling 設定の妥当性
### 2. セキュリティ
- IAM ポリシーの過剰権限
- パブリックアクセスの不要な公開
- シークレット管理の不備
- ログ・監査証跡不足
### 3. 運用・保守性
- ログ、メトリクス、アラート不足
- 障害調査が困難になる構成
- 環境差分による事故リスク
### 4. コスト
- 無駄に高コストになり得る構成
- 開発・検証環境での過剰スペック
- 常時起動リソースの妥当性
### 5. CDK設計観点
- Stack / Construct の責務分離
- ハードコード値の多用
- Context / Parameter Store / Secrets Manager の使い分け
- 将来の拡張性
---
## 出力フォーマット(厳守)
検出した **問題点ごと** に、必ず以下の形式で出力してください。
### 問題点 X
- **概要**
(何が問題かを簡潔に)
- **根拠**
(どのコード・設定・設計思想が原因か。AWSベストプラクティスや一般的知見に基づいて説明)
- **想定される影響**
(障害内容、セキュリティリスク、運用負荷、コスト増など)
- **修正方針・改善案**
(設計レベル・CDK修正例・AWSサービス選定含む。可能であれば具体的な対応)
---
## 重要な指示
- 問題が「起き得る可能性が低い」場合でも、**本番システムとして無視できないものは必ず指摘**してください
- 推測の場合は「推測である」ことを明示してください
- 問題が見つからない場合でも「現状問題なし」とせず、**将来リスク・改善余地**を必ず提示してください
---
## 出力方法
- レビュー結果は **Markdown形式** でまとめてください
- 最終出力は以下のファイルとして保存する前提で記述してください
以下は必須項目としました。
・問題点
・問題としたその根拠
・想定される影響
・修正案
単純なAIによるコードレビューやAWS Fault Injection Simulator(FIS)との比較
・単純なAIレビュー:構文・ロジックの誤り、可読性・保守性がメイン
・FIS:構築後に検証、事前設計が必要
⇒今回はAWS構成・設計・運用をメインに壊れたらどうなるかまでレビューできる
出力結果の確認
コードは事前にAIを使った単純なレビューやセルフレビューを通していくつか問題となりそうな部分は洗い出しておきました。
Copilot
- 検知した問題数:17(内8件は事前レビューで検知済み、5件は過剰検知)
- 修正内容について細かく具体的なコードがありわかりやすい
- しかもコピペできる形で修正がしやすかった
- 優先度で分類までしてくれており、サマリも出力してくれていた
- チェック観点が少し過剰な気もした
実際の出力の一部
### 問題点 1: セキュリティ - Lambda実行ロールの過剰権限リスク
- **概要**
Lambda関数に付与されるIAM権限が明示的に制限されておらず、CDKが自動生成するロールに依存している
- **根拠**
`topic.grantPublish(logProcessorFunction)` でSNS発行権限を付与しているが、Lambda実行ロール全体の権限範囲が明示されていない。AWS Well-Architected Framework のセキュリティピラーでは最小権限の原則を推奨している
- **想定される影響**
- Lambda関数が意図しないAWSリソースにアクセス可能になる可能性
- セキュリティ監査時に権限の妥当性検証が困難
- 将来的な機能拡張時に権限の肥大化リスク
- **修正方針・改善案**
明示的なIAMロールとポリシーを定義し、必要最小限の権限のみを付与
const lambdaRole = new iam.Role(this, 'LogProcessorRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
managedPolicies: [
iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole')
],
inlinePolicies: {
SNSPublishPolicy: new iam.PolicyDocument({
statements: [
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['sns:Publish'],
resources: [topic.topicArn]
})
]
})
}
});
Amazon Q
- 検知した問題数:6(内5件は事前レビューで検知済み、1件は過剰検知)
- 指摘内容については適切であるが、修正方針が曖昧
- 具体的なコード等がなくわかりづらった
- 既存コードの把握に強い想定であったが、他AIと比較すると出力が弱く感じた
実際の出力の一部
問題点 1: セキュリティ - IAM権限の過剰付与
概要: Lambda関数に対するCloudWatch Logsからの実行権限が広範囲すぎる可能性
根拠: sourceArnでワイルドカード(*)を使用している
想定される影響: 意図しないログストリームからのLambda実行、セキュリティリスク
修正方針: より具体的なARN指定、最小権限の原則適用
Kiro(Vibeモード)
- 検知した問題数:10(内7件は事前レビューで検知済み、1件は過剰検知)
- Copilotと同じく修正案の具体的なコードと、優先度の分類がされていてよかった
- Kiroは仕様書作成などに強く、SpecモードもあるのでKiroの機能としてはこれだけではないこと留意したい
実際の出力の一部
### 問題点 1: Lambda タイムアウト時の無限ループおよび逆流制御の欠如
- **概要**
CloudWatch Logs Subscription Filter → Lambda の構成において、Lambda実行が失敗(タイムアウト、エラー等)した際の再試行メカニズムが明示的に設定されていません。Lambda実行がタイムアウトした場合、CloudWatch Logs側では「トライ」と判定され、その行動が明確に定義されていません。
- **根拠**
[log-notification-stack.ts](log-notification-stack.ts#L60-L62) の `SubscriptionFilter` 定義において、`retryPolicy` や `deadLetterConfig` が指定されていません。AWS CDK の `LambdaDestination` では、これらのプロパティを明示的に指定する必要があります。CloudWatch Logs Subscription Filter は、デフォルトでは同期実行となり、失敗時の再試行ポリシーが不明確です。
Lambda タイムアウトは [log-notification-stack.ts](log-notification-stack.ts#L47) で `timeout: cdk.Duration.minutes(1)` に設定されていますが、SNS発行の遅延、ネットワーク不安定性、または複数ログイベント処理時に タイムアウトが発生する可能性があります。
- **想定される影響**
- 本番環境でログ大量発生時に Lambda タイムアウト → CloudWatch Logs の処理が遅延/ハング
- ログが失われる可能性、または CloudWatch Logs Subscription Filter が自動無効化される
- アラート漏れが発生し、障害を見落とす可能性
- Lambda エラーログのみが記録され、根本原因の調査が困難
- **修正方針・改善案**
1. **Lambda タイムアウト値の増加**
複数ログイベント処理を考慮して、タイムアウトを3〜5分に設定
2. **Dead Letter Queue (DLQ) の導入**
Lambda に DLQ(SQS または SNS)を設定し、失敗イベントを保留
3. **バッチ処理の最適化**
ログイベント1件ごとに SNS 発行せず、複数イベントをまとめて発行
4. **Explicit Retry Policy の設定**
CDK で `LambdaDestination` の `candles` オプション活用(手動実装の場合)
// 改善例:バッチ処理+DLQ設定
const logProcessorFunction = new lambda.Function(this, 'LogProcessorFunction', {
runtime: lambda.Runtime.NODEJS_18_X,
handler: 'index.handler',
code: lambda.Code.fromAsset(path.join(__dirname, '../lambda')),
environment: {
SNS_TOPIC_ARN: topic.topicArn
},
timeout: cdk.Duration.minutes(5),
onFailure: new lambda.SqsQueue(dlq), // Dead Letter Queue
memorySize: 512 // Increase memory to improve performance
});
まとめ
- 今回はcopilotが新規検知4件で最も検知に優れている結果となりました。
- また、AIの選定だけでなく用途に応じたプロンプト作成も大事だと感じました。
- 現在は業務に活かしたりなどはできてませんが、ローカルの私の開発では結構役に立ってます。
- 今後はGitHub Acitonsなどに取り込んで自動化なども行ってみたいです。
今回触れられなかったAIも多々ありますので、今後はそれらについても検証をしていきたいです。
また、使用するエンジンやコストなどの観点には今回触れられなかったので是非皆さんも調べてみてください。
