第1部はこちら → https://qiita.com/REALKTMR/items/325e5c5726c0989ade1c
はじめに
第1部では、KiroのバイブコーディングモードでAWS三層アーキテクチャのCloudFormationテンプレートを生成し、Well-Architected Framework(以下WA)の6本柱30項目で採点しました。
結果は以下の通りでした:
| パターン | 採点結果 | 特徴 |
|---|---|---|
| Pattern A(バイブ・最小プロンプト) | 12/30 | 「三層アーキテクチャを作って」のみ |
| Pattern B(バイブ・WA指示あり) | 26/30 | 「WA 6本柱に準拠」と明示 |
Pattern Bで26点まで上がりましたが、ALBアクセスログやHTTPSなど設計書に書いたのに実装されなかった項目がありました。
第2部のテーマは「Kiro Specモードなら同じプロンプトでどこまで改善するか」 です。
同じプロンプトをSpecモードに投入したSpec A(28/30)と、詳細な仕様書を事前定義したSpec B(30/30 満点)の2パターンを検証します。
検証環境
| 項目 | 内容 |
|---|---|
| ツール | Kiro(IDE、Specモード) |
| 対象 | AWS CloudFormation(三層アーキテクチャ) |
| 採点 | score_templates.py(自作採点スクリプト) |
| リポジトリ | https://github.com/realktmr/kiro-iac-sample1 |
Kiro Specモードとは
Kiroには大きく2つのモードがあります。
- バイブコーディングモード:チャット感覚でプロンプトを入力すると、そのままコードを生成する
- Specモード:「要件 → 設計 → タスク → 実装」の構造化フローで段階的に生成する
Specモードでは、ユーザーが最初に意図(もしくは仕様書)を入力すると、Kiroが自律的に以下のドキュメントを生成します。
1. requirements.md → ユーザーストーリーと受け入れ条件(EARS記法)
2. design.md → アーキテクチャ設計、コンポーネント図、データフロー
3. tasks.md → 実装タスクの分解(チェックリスト形式)
4. 実装 → tasks.mdを参照しながら順番にコードを生成
このフローがバイブコーディングとの決定的な違いです。「書いた要件は必ず実装フェーズまで追跡される」 という構造になっています。
Spec A:同じプロンプトをSpecモードに投入
使用プロンプト
第1部Pattern Bと同じプロンプトをSpecモードに入力しました。
AWSの三層アーキテクチャ(Web/App/DB)をCloudFormationで構築してください。
Well-Architected Framework の6本柱(運用上の優秀性・セキュリティ・信頼性・
パフォーマンス効率・コスト最適化・持続可能性)に準拠すること。
Kiroの動き:requirements.mdの生成
Specモードに入力すると、Kiroはまずプロンプトを解析して requirements.md を生成します。この段階でKiroは「WA 6本柱への準拠」という要件を構造化し、各柱に対する受け入れ条件をEARS記法で記述しました。
生成された requirements.md の一部(抜粋):
## Functional Requirements
### FR-1: Network Architecture
- WHEN the stack is deployed, the system SHALL create a VPC with public and private subnets
across multiple Availability Zones
- The system SHALL deploy EC2 instances in private subnets only
- The system SHALL use an Application Load Balancer in public subnets
### FR-2: Security
- The system SHALL store database credentials in AWS Secrets Manager
- The system SHALL enable encryption at rest for RDS
- The system SHALL enforce IMDSv2 on EC2 instances (HttpTokens: required)
- The system SHALL enable VPC Flow Logs for network visibility
### FR-3: Reliability
- The system SHALL deploy RDS with Multi-AZ enabled
- The system SHALL use Auto Scaling Groups for EC2 instances
- The system SHALL set DeletionPolicy: Snapshot on RDS
バイブコーディングとの違いが明確です。 Pattern Bでは「WA 6本柱に準拠」というプロンプトをそのまま解釈してコードを生成しましたが、Specモードでは一度「受け入れ条件」に分解してから実装に入ります。この段階で「何を実装するか」が明文化されます。
続いて design.md、tasks.md が生成され、tasks.mdの各チェック項目を順番に実装していく形でテンプレートが生成されました。
生成されたテンプレートの特徴
| カテゴリ | 項目 | 内容 |
|---|---|---|
| ネットワーク | VPC | パブリック/プライベートサブネット、マルチAZ |
| コンピュート | EC2 | t4g.small(Graviton2) + ASG + LaunchTemplate |
| コンピュート | スケーリング | TargetTracking(CPU 70%) |
| ストレージ | EBS | gp3 + 暗号化 |
| データベース | RDS | Multi-AZ、暗号化、DeletionPolicy:Snapshot |
| データベース | RDSストレージ | デフォルト(gp2) ← ここが後のSpec Bとの差 |
| セキュリティ | 認証情報 | Secrets Manager |
| セキュリティ | メタデータ | IMDSv2(HttpTokens: required) |
| セキュリティ | HTTPS | ACM + CertificateArn パラメータ |
| 可視性 | ログ | VPC Flow Logs + ALBアクセスログ(S3) |
| 監視 | アラーム | CloudWatchアラーム 4つ + SNS通知 |
特筆すべきは、バイブコーディングPattern Bで実装されなかったHTTPS・ALBアクセスログ・VPC Flow Logsがすべて実装された 点です。
Pattern Bでは設計書にHTTPSと書いたのに、実装フェーズで抜け落ちました。Specモードではrequirements.md → design.md → tasks.md → 実装というトレーサビリティが保たれているため、要件として書いた内容は実装まで追跡されます。
プロパティベーステスト:Kiroが自律的に実行
Spec Aの実装中、Kiroは自律的に test_template_properties.py を作成し、実行しました。このテストはCloudFormationテンプレートのプロパティ(リソースの存在・設定値)を検証するものです。
全テストがパスしました。しかし、ここに落とし穴がありました。
セマンティックバグ:テストをすり抜けたバグ
生成されたテンプレートのUserDataに以下のコードが含まれていました。
<?php
$host = '${DBSecret}'; // ← ここがバグ
$dbname = 'appdb';
$host = '${DBSecret}' はSecrets ManagerのARN文字列(arn:aws:secretsmanager:ap-northeast-1:xxxx:secret:xxx)をDBホスト名として使っています。正しくは ${DBInstance.Endpoint.Address} です。
プロパティテストは「DBSecret というリソースが存在するか」「!Ref DBSecret という参照が有効か」は検証できます。しかし 「そのリソースの値がDBホスト名として意味をなすか」 というセマンティクスは検証できません。
DBSecret は確かにテンプレート内に存在するリソースなので、Ref参照の整合性チェックはパスしてしまいます。
教訓:プロパティテストは構造バグを見つけるが、セマンティックバグは見逃す
テストが全部パスしてもデプロイしてから気づくバグがある。インフラのテストを書くときは「値の意味」まで検証する項目を意識的に追加する必要がある。
Spec B:詳細な仕様書を事前に定義する
spec-three-tier.mdの作成
Spec Aの結果(28/30)を分析すると、失点はRDSのgp3未指定による2点のみでした(PERF-3とSUST-4)。Kiroがデフォルト(gp2)を選択したのは、プロンプトにもrequirements.mdにも「RDSのStorageTypeはgp3」という記述がなかったためです。
「書いていないことはAIが判断する。書いてあることは指定通りに実装する。」
この仮説を検証するため、Spec BではKiroへの入力として詳細な仕様書 spec-three-tier.md を事前に作成しました。
# 三層アーキテクチャ仕様書
## ストレージ仕様
- EBS: gp3(EC2インスタンス)
- RDS: StorageType: gp3を明示すること ← ここを追加
- RDS StorageSize: 20GB
## コンピュート仕様
- EC2: t4g.micro(Graviton2、コスト最適化)
- ASG: TargetTracking(CPU 70%)
## セキュリティ仕様
- Secrets Manager: DBパスワード管理
- IMDSv2: HttpTokens: required
- RDS暗号化: StorageEncrypted: true
- EBS暗号化: Encrypted: true
(以下略)
生成されたRequirements.mdとDesign.md
Kiroは spec-three-tier.md を解析し、より詳細な requirements.md を生成しました。注目点は以下です。
## FR-4: Storage Optimization
- The system SHALL use gp3 storage type for RDS instances (StorageType: gp3)
← spec-three-tier.mdの記述がそのまま受け入れ条件になっている
- The system SHALL use gp3 storage type for EBS volumes
- WHEN storage type is specified, the system SHALL NOT use default (gp2)
design.md では、RDSのストレージ設定が明示的にgp3として設計されており、tasks.mdにも「StorageType: gp3をRDSリソースに設定する」というチェック項目が含まれていました。
生成されたテンプレートの特徴
| カテゴリ | 項目 | Spec A | Spec B |
|---|---|---|---|
| コンピュート | インスタンスタイプ | t4g.small | t4g.micro |
| データベース | RDSストレージタイプ | デフォルト(gp2) | gp3(明示) |
| セキュリティ | SGIngress定義 | SGリソース内にインライン | AWS::EC2::SecurityGroupIngress(独立) |
| その他 | Spec A同等機能 | すべてあり | すべてあり |
Spec BではSecurityGroupのIngressルールを独立したリソース(AWS::EC2::SecurityGroupIngress)として定義しています。これはSecurityGroup間の循環参照を回避するためのベストプラクティスで、仕様書に「独立したリソースとして定義」と書いたことが反映されました。
プロパティベーステスト
Spec BでもKiroは自律的に test_template_properties.py を作成・実行しました。
def test_rds_storage_type_gp3():
"""RDSのStorageTypeがgp3であることを確認"""
rds_props = template["Resources"]["DBInstance"]["Properties"]
assert rds_props.get("StorageType") == "gp3", \
f"RDS StorageType should be gp3, got: {rds_props.get('StorageType', 'not set')}"
Spec Aのテストと比較すると、Spec BのテストはRDSのStorageTypeを明示的にgp3と検証しています。仕様書に「gp3を使うこと」と書いたことで、テストコードにも「gp3かどうか検証する」という項目が追加されました。
全テストパス。かつSpec Aで発生したセマンティックバグ($host = '${DBSecret}')もSpec Bでは修正されていました(仕様書のDB接続設定の記述がより具体的だったため)。
4パターン比較:Well-Architected 30項目チェック
採点はAWS Well-Architected Frameworkの設問(OPS/SEC/REL/PERF/COST/SUSの各柱から評価可能な設問を選定)に対応した30項目のベストプラクティスチェックです。
WA設問対応表(30項目 × 4パターン)
| 評価項目 | 対応WA設問 | PatA | PatB | SpecA | SpecB |
|---|---|---|---|---|---|
| 運用上の優秀性 | |||||
| VPC Flow Logs | OPS04 運用可視性の実装 | ❌ | ✅ | ✅ | ✅ |
| CloudWatch Alarms | OPS08 ワークロード健全性の把握 | ❌ | ✅ | ✅ | ✅ |
| SSM IAMロール | OPS07 ワークロードのサポート準備 | ❌ | ✅ | ✅ | ✅ |
| ヘルスチェック設定 | OPS08 | ✅ | ✅ | ✅ | ✅ |
| ALBアクセスログ(S3) | OPS04 | ❌ | ❌ | ✅ | ✅ |
| セキュリティ | |||||
| EC2プライベートサブネット | SEC05 ネットワークリソースの保護 | ✅ | ✅ | ✅ | ✅ |
| SGソース制限 | SEC05 | ✅ | ✅ | ✅ | ✅ |
| Secrets Manager | SEC08 保存データの保護 | ❌ | ✅ | ✅ | ✅ |
| RDS暗号化 | SEC08 | ❌ | ✅ | ✅ | ✅ |
| EBS暗号化 or IMDSv2 | SEC06 コンピュートリソースの保護 | ❌ | ✅ | ✅ | ✅ |
| 信頼性 | |||||
| EC2マルチAZ | REL10 障害分離 | ✅ | ✅ | ✅ | ✅ |
| RDSバックアップ7日 | REL09 データバックアップ | ✅ | ✅ | ✅ | ✅ |
| RDS Multi-AZ | REL10 | ❌ | ✅ | ✅ | ✅ |
| ASG自動復旧 | REL07 需要変動への対応 | ❌ | ✅ | ✅ | ✅ |
| DeletionPolicy:Snapshot | REL09 | ❌ | ✅ | ✅ | ✅ |
| パフォーマンス効率 | |||||
| TargetTracking | PERF02 コンピュートのプロビジョニング | ❌ | ✅ | ✅ | ✅ |
| gp3 EBS | PERF03 ストレージ選択 | ❌ | ✅ | ✅ | ✅ |
| gp3 RDS | PERF03 | ✅ | ✅ | ❌ | ✅ |
| Graviton(t4g) | PERF01 コンピュートアーキテクチャ選択 | ❌ | ❌ | ✅ | ✅ |
| 最新世代インスタンス | PERF01 | ✅ | ✅ | ✅ | ✅ |
| コスト最適化 | |||||
| Graviton(コスト) | COST06 リソースタイプ・サイズ選択 | ❌ | ❌ | ✅ | ✅ |
| 単一NAT GW | COST05 サービス選択時のコスト評価 | ✅ | ✅ | ✅ | ✅ |
| gp3ストレージ | COST06 | ✅ | ✅ | ✅ | ✅ |
| Auto Scaling | COST09 需要と供給の管理 | ❌ | ✅ | ✅ | ✅ |
| 適切インスタンスタイプ | COST06 | ✅ | ✅ | ✅ | ✅ |
| 持続可能性 | |||||
| Graviton(省電力) | SUS05 ハードウェア選択 | ❌ | ❌ | ✅ | ✅ |
| Auto Scaling(省エネ) | SUS02 需要へのリソース整合 | ❌ | ✅ | ✅ | ✅ |
| gp3 EBS(効率) | SUS03 持続可能なアーキテクチャ | ❌ | ✅ | ✅ | ✅ |
| gp3 RDS(効率) | SUS03 | ✅ | ✅ | ❌ | ✅ |
| 最新世代インスタンス | SUS05 | ✅ | ✅ | ✅ | ✅ |
採点結果サマリー
| パターン | OE | SEC | REL | PERF | COST | SUST | 合計 |
|---|---|---|---|---|---|---|---|
| Pattern A(バイブ・最小) | 1 | 2 | 2 | 2 | 3 | 2 | 12/30 |
| Pattern B(バイブ・WA指示) | 4 | 5 | 5 | 4 | 4 | 4 | 26/30 |
| Spec A(Spec・WA指示) | 5 | 5 | 5 | 4 | 5 | 4 | 28/30 |
| Spec B(Spec・詳細仕様) | 5 | 5 | 5 | 5 | 5 | 5 | 30/30 |
スコアから読み取れること
Specモード vs バイブコーディング(同プロンプト)
同じプロンプトでもSpecモードの方が2点高い(26 → 28)。
差分は2項目です:
| 差分項目 | Pattern B | Spec A |
|---|---|---|
| ALBアクセスログ(S3) | ❌ | ✅ |
| Graviton(t4g)※PERF・COST・SUST各1点に加算 | ❌ | ✅ |
ALBアクセスログはPattern Bの設計書にも記載がありましたが、実装フェーズで抜け落ちました。Specモードではrequirements.md → design.md → tasks.md → 実装というトレーサビリティが保証されているため、要件に書いた内容は実装まで追跡されます。
Gravitonについては、Pattern Bのプロンプトには「Gravitonを使え」という指示はありませんでした。Specモードでは「コスト最適化」「持続可能性」の受け入れ条件を自律的に生成する際、Gravitonプロセッサの採用を判断基準に含めました。構造化された要件定義フローが、AIの「判断」の質を上げています。
Spec A vs Spec B(仕様書の差)
Spec AとSpec Bの差はたった2点(PERF-3とSUST-4、どちらもgp3 RDS)。
| 失点項目 | 理由 |
|---|---|
| PERF-3 gp3 RDS | プロンプト・仕様書にStorageType: gp3の指定なし |
| SUST-4 gp3 RDS(効率) | 同上(同一根本原因) |
Kiroは「RDSを作る」という要件は正確に実装しましたが、StorageTypeを明示しなかったためCloudFormationのデフォルト(gp2)が使われました。
Spec Bでは spec-three-tier.md に「RDSはStorageType: gp3を使うこと」と1行追加しただけで、満点になりました。
まぁ、でもこれはAIが判断できる情報を与えなかったからとも言えます。gp3がマッチするかは、COST、PERF、SUSTの3項目にある総和で決まり、必要なIOPSがいくつで、スループットがいくつで、と書いてあげないとgp2がいいのかgp3がいいのかは判断できないです。
AIは「書いてあること」は正確に実装する。「書いていないこと」はデフォルトか推論で判断する。
仕様書の精度がそのままIaCの品質になる。これがSpecモードの本質です。
変わらなかった部分
4パターンを通じて、すべてのパターンで最初から正しく実装されていた項目があります。
| 項目 | 内容 |
|---|---|
| EC2プライベートサブネット | バイブ最小でも正しく配置 |
| SGソース制限 | ALB → EC2 → RDS の制限が一貫して正しい |
| EC2マルチAZ | 常にマルチAZ構成 |
| RDSバックアップ7日 | デフォルト設定として常に含まれる |
| 単一NAT GW | コスト意識が最小プロンプトでも反映 |
| 最新世代インスタンス | t系最新世代が常に選ばれる |
これらはCloudFormationのベストプラクティスとして広くドキュメント化されており、LLMのトレーニングデータに十分含まれていると考えられます。「最低限の品質」はある程度保証されているということです。
考察
Specモードの価値は「トレーサビリティ」
バイブコーディングとSpecモードの本質的な違いは、「プロンプト → コード」という直接変換か、「プロンプト → 要件 → 設計 → タスク → コード」という構造化された変換かです。
この差がIaC品質に与える影響は2点です:
- 抜け漏れが減る:要件として明文化されたものはタスクとして分解され、実装まで追跡される
- 判断の質が上がる:設計フェーズで一度立ち止まることで、Gravitonのような「明示されていないが推奨される選択」もより多く取り込まれる
仕様書の精度がIaCの品質を決める
Spec AとSpec Bの差(28点 vs 30点)は仕様書の精度の差でした。
これはKiroに限った話ではなく、あらゆるAIコーディングツールに共通する原則です。「AIに任せれば良いコードが出る」のではなく、「良い仕様書を書けば良いコードが出る」 という関係性です。
インフラエンジニアにとってこれは朗報です。IaCのベストプラクティスを知っているエンジニアが「何を仕様書に書くべきか」を判断し、AIに実装させるという役割分担が明確になります。
プロパティテストの限界と次のステップ
Spec Aのセマンティックバグは、プロパティテストをすり抜けました。構造的な正しさ(リソースの存在・参照の整合性)は自動検証できても、意味的な正しさ(その値が実際に意図した用途に合っているか)はより高度なテストが必要です。
次のステップとして考えられるのは:
- 統合テスト:実際にスタックをデプロイして動作確認
- コントラクトテスト:「DBホスト名はIPアドレスかFQDNの形式であること」のような意味的な検証
- コードレビュー:AIの出力であっても人間がUserDataを確認するフロー
まとめ
| パターン | スコア | 一言 |
|---|---|---|
| Pattern A(バイブ・最小) | 12/30 | 最低限の構造は作れる |
| Pattern B(バイブ・WA指示) | 26/30 | プロンプト次第でかなり上がる |
| Spec A(Spec・WA指示) | 28/30 | 同プロンプトでもSpecモードが優秀 |
| Spec B(Spec・詳細仕様) | 30/30 | 仕様書の精度が満点をもたらす |
第2部で確認できたこと:
- Specモードはバイブコーディングより2点高い(同プロンプトで26 → 28)
- トレーサビリティが「書いたことを実装する」を保証する(ALBログ・HTTPSの実装漏れが解消)
- Gravitonのような判断もSpecモードで自律的に取り込まれた
- 詳細仕様書が満点をもたらした(gp3 RDSの1指定で28 → 30)
- プロパティテストは構造バグを見つけるがセマンティックバグは見逃す
インフラエンジニアがKiroのSpecモードを使うとき、最も時間をかけるべきは仕様書の作成です。WA 6本柱の各項目を仕様書に落とし込む作業こそが、AIに良いIaCを生成させる鍵です。
検証コード(GitHub)
全テンプレート・採点スクリプト・テストコードはこちら:
kiro-iac-sample1/
├── pattern-2a/ # 第2部 Spec A
│ ├── requirements.md
│ ├── design.md
│ ├── tasks.md
│ └── template.yaml
├── pattern-2b/ # 第2部 Spec B
│ ├── spec-three-tier.md
│ ├── requirements.md
│ ├── design.md
│ ├── tasks.md
│ └── template.yaml
└── score_templates.py # WA 30項目採点スクリプト
次回予告:第3部
第3部では Kiro の Agent Hooks と AWS CI/CD でインフラ変更を安全に適用する 仕組みを構築します。
CloudFormation テンプレートを変更するとき、「本当に壊れないか」を担保するにはどうすればいいか。Kiro の Agent Hooks でローカルバリデーションを自動化し、CodePipeline + CodeBuild で Change Set レビューからデプロイまでを AWS だけで完結させるパイプラインを作ります。
お楽しみに。