KiroでTerraformコードのテストをする

本記事は 夏休みクラウド自由研究2025 8/25付の記事です

こんにちは、稲葉です。
近年次々と生成AIの技術が登場して、めまぐるしいですね。
クラウド自由研究の記事をきっかけに触ってみようと思いました。

先日AWSからリリースされたKiroは、AIが仕様書やタスクリストを作成しながら実装を行ってくれる「仕様駆動開発」が特徴です。
以下の記事に仕様駆動開発の流れが紹介されています。

Hey Kiro, Spotifyのプレイリストで打線組んで。
AWSが発表した次世代エージェント型IDE「Kiro」を実際に触ってみて、Webアプリケーションを構築してみた体験記となります。

未来を感じたので私もKiroを触ってみようと思います。

本記事では、Kiroで下記4つの内容を試してみようと思います。

  • Agent Steering機能を試す 
  • Agent Hooks機能を試す
  • 既存のコードを読み取り、仕様書を生成する
  • Terraformのテストコードの作成とテストを実施する

また、下記2つのMCPサーバーを利用しています。

  • awslabs-aws-documentation-mcp-server
  • awslabs-aws-terraform-mcp-server

 

用意したTerraformコード

下記のようなシンプルな構成のTerraformコードを用意しました。

. 
├──  main.tf <- new!
└── .kiro 
  └── settings 
    └── mcp.json

EC2インスタンスのパブリックIPにアクセスすると、hello worldと返ってくるようにしています。
また、セッションマネージャーでインスタンスにアクセスできるようにしています。

Terraformコード(main.tf)

terraform {
  backend"local" {
    path="kiro-test.tfstate"
  }
  required_providers {
    aws={
      source="hashicorp/aws"
      version="~> 5.57.0"
    }
  }
}

provider "aws" {
  region="ap-northeast-1"
  profile="<プロファイル>"
}

# VPC
resource "aws_vpc" "vpc" {
  cidr_block="10.0.0.0/16"
}
resource "aws_internet_gateway" "igw" {
  vpc_id=aws_vpc.vpc.id
}
resource "aws_subnet" "public_subnet" {
  vpc_id=aws_vpc.vpc.id
  cidr_block="10.0.1.0/24"
  availability_zone="ap-northeast-1a"
  map_public_ip_on_launch=true
}

# ルートテーブル
resource "aws_route_table" "public_route" {
  vpc_id=aws_vpc.vpc.id
  route {
    cidr_block="0.0.0.0/0"
    gateway_id=aws_internet_gateway.igw.id
  }
}
resource "aws_route_table_association" "public_route_association" {
  subnet_id=aws_subnet.public_subnet.id
  route_table_id=aws_route_table.public_route.id
}

# EC2インスタンス用セキュリティグループ
resource "aws_security_group" "web_sg" {
  name="web-sg"
  description="Allow HTTP from specific IP"
  vpc_id=aws_vpc.vpc.id
}
resource "aws_vpc_security_group_ingress_rule" "allow_http_rule" {
  security_group_id=aws_security_group.web_sg.id
  cidr_ipv4="<接続を許可するIPアドレス>"
  from_port=80
  ip_protocol="tcp"
  to_port=80
}
resource "aws_vpc_security_group_egress_rule" "egress_rule" {
  security_group_id=aws_security_group.web_sg.id
  cidr_ipv4="0.0.0.0/0"
  from_port=0
  ip_protocol="-1"
  to_port=0
}

# SSM用IAMロール
resource "aws_iam_role" "ssm_role" {
  name="ec2-ssm-role"
  assume_role_policy=jsonencode({
    Version="2012-10-17"
      Statement= [{
        Action="sts:AssumeRole"
        Effect="Allow"
        Principal= {
          Service="ec2.amazonaws.com"
        }
     }]
  })
}
resource "aws_iam_role_policy_attachment" "ssm_attach" {
  role=aws_iam_role.ssm_role.name
  policy_arn="arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
resource "aws_iam_instance_profile" "ssm_profile" {
  name="ec2-ssm-profile"
  role=aws_iam_role.ssm_role.name
}

# EC2
resource "aws_instance" "web_instance" {
  ami="ami-0f36dcfcc94112ea1"# Amazon Linux 2 (東京)
  instance_type="t3.micro"
  subnet_id=aws_subnet.public_subnet.id
  vpc_security_group_ids=[aws_security_group.web_sg.id]
  iam_instance_profile=aws_iam_instance_profile.ssm_profile.name
  user_data=<<-EOF
    #!/bin/bash
    yum update -y
    amazon-linux-extras install nginx1 -y
    systemctl enable nginx
    systemctl start nginx
    echo "hello world" > /usr/share/nginx/html/index.html
    EOF
}

Agent Steeringを試す

Agent Steeringはプロジェクトに関する知識をKiroに与えるための機能です。
プロジェクトで作成するアプリケーションについての知識や、プロジェクトで使用するツールについての知識、プロジェクトを進める上でのルールについての知識など、さまざまな知識を与えることができます。

プロジェクトを進める上での2つのルールを設定しようと思います。

  • やりとりを日本語で行うこと
  • 作成されるリソースにはタグが付いていること

やりとりの日本語化

KiroのVibeモードでやりとりを日本語化するSteeringの作成をお願いしました。

Kiroとのやりとりを日本語で行うようにするSteeringファイルを作成してください

するとプロジェクトフォルダの.kiroディレクトリ内にSteering用のディレクトリが作成され、その中に作成をお願いしたSteeringファイルができていました。

.
├── main.tf
└── .kiro
  ├── settings
  │ └── mcp.json
  └── steering      <- new!
    └── language.md <- new!

Steeringファイルはマークダウン形式で書かれていて、人間が呼んでもわかりやすい形式になってました。
日本語化のお願いのほかにも、コミュニケーションのスタイルや日本語化しないことまで設定してくれていて気が利きますね!

---
inclusion: always
---

# 日本語コミュニケーションガイドライン

## 基本言語設定
- **主要言語**: すべての回答とコミュニケーションは日本語で行う
- **コード内コメント**: 日本語でコメントを記述
- **ドキュメント**: README、設計書等も日本語で作成
- **エラーメッセージ**: 可能な限り日本語で説明

## コミュニケーションスタイル
- **敬語**: 丁寧語を基本とし、親しみやすい口調を心がける
- **専門用語**: 必要に応じて英語の技術用語も併記(例:コンテナ(Container))
- **説明方法**: 段階的で分かりやすい説明を提供
- **質問対応**: 不明な点は積極的に確認する

## 文書作成ルール
- **見出し**: 階層構造を明確にする
- **箇条書き**: 情報を整理して提示
- **コード例**: 日本語コメント付きで提供
- **手順書**: ステップバイステップで記述

## 例外事項
- **コマンド**: CLIコマンドは英語のまま
- **設定ファイル**: JSON、YAML等の設定値は英語
- **URL・パス**: ファイルパスやURLは英語
- **ログ出力**: システムログは元の言語のまま

## 対応範囲
- **技術説明**: インフラ、開発、運用すべて日本語
- **トラブルシューティング**: 問題解決も日本語で対応
- **ベストプラクティス**: 推奨事項も日本語で提示
- **レビューコメント**: コードレビューも日本語

ヘッダーの下記記述は、Steeringファイルを読み込むタイミングを設定する箇所です。

---
inclusion: always
---

3つのタイミングを設定できます

  • always(default): 常にこのSteeringファイルを読む
  • fileMatch: 指定したファイルを扱うときにこのSterringファイルを読む
  • manual: 通常このSteeringファイルを読まない。チャットで#<Sterringファイル名>のように指定した時だけ読む
Steering - Docs - Kiro
Guide Kiro's AI with project-specific context through markdown documents that define your standards, architecture, and c...

作成するリソースへのタグ付け

次にTerraformで作成されるリソースにタグを付与するよう、設定の作成をお願いしました。

このプロジェクトのTerraformから生成される全てのAWSリソースに次のタグを付与するルールを記載してください。
- ManagedBy: Terraform
- Project: Kiro-test

先ほどのように.kiro/steeringの下にtag-rules.mdというSteeringファイルができていました。
default_tagsでTerraformが生成するすべてのリソースにManagedByタグとProjectタグを付与する設定をしていますね。
また、各リソースにはdefault_tagsで付与するタグの他にNameタグとEnvironmentタグを付与する設定になっています。
いい感じですね!

---
inclusion: always
---

# AWS リソースタグ付与ルール

## 必須タグ
Kiroで生成・管理する全てのAWSリソースには以下のタグを必ず付与すること:

### 基本タグ(このプロジェクト固有)
- **ManagedBy**: `Terraform` - Terraformによって管理されていることを示す
- **Project**: `Kiro-test` - このプロジェクト専用の識別子

## Terraformでの実装例
### リソース共通タグ
```hcl
locals {
    common_tags = {
        ManagedBy = "Terraform"
        Project = "Kiro-test"
    }
}
```

### プロバイダーレベルでのデフォルトタグ
```hcl
provider "aws" {
    default_tags {
        tags = local.common_tags
    }
}
```

## 適用ルール
1. **全リソース必須**: EC2、S3、RDS、Lambda等すべてのAWSリソース
2. **一貫性**: プロジェクト内で統一されたタグ命名規則
3. **自動化**: Terraformのlocalsとdefault_tagsを活用
4. **検証**: タグが正しく付与されているかの確認を含める

## 例外処理
- 一時的なテストリソースでも必須タグ(`ManagedBy: Terraform`, `Project: Kiro-test`)は必須
- サードパーティサービス連携で制限がある場合は代替手段を検討

## プロジェクト固有設定
このプロジェクト「Kiro-test」では以下の固定値を使用:
- **ManagedBy**: 必ず `Terraform` を設定
- **Project**: 必ず `Kiro-test` を設定

### 実装例

```hcl# 全リソースに自動適用
provider "aws" {
    default_tags {
        tags = {
            ManagedBy = "Terraform"
            Project = "Kiro-test"
        }
    }
}

# 個別リソースでの追加タグ例
resource "aws_instance" "example" {
    # ... その他の設定 ...
    tags = merge(local.common_tags, {
        Name = "example-instance"
        Environment = "dev"
    })
}
```

コードから仕様書を生成する

Kiroではspecsという単位でプロジェクトを管理し、下記3フェーズでシステムを構築します。

  • requirements : 要件定義
  • design: 技術設計
  • tasks: タスクリストの作成、実行

tasksフェーズが終了後、Kiroは仕様書を作成します。

本稿では既存のterraformファイルをKiroに読み込ませ、上記フェーズの実施と仕様書の生成ができるか確かめようと思います。

要件定義フェーズ

次の画像のように、vibeモードでspecsの作成をお願いしました。
specsを作成すると、1番目の要件定義フェーズに入ります。

このフェーズは、プロンプトで指定した内容から要件を定義し、requirements.mdというファイルにまとめるフェーズです。

やりとりを見ていくと、1行目では日本語化するSteeringが効いていませんね。
この行はKiroがプロンプトの内容からSpecモードの方が適切だと判断し、VibeモードからSpecモードに切り替えましょうかという提案をしてきている内容でした。Yesで切り替えました。
1行目以外では日本語でやりとりできています。
タグ付けルールのSteeringは効いていて、必須タグが設定されていないよと指定してくれています。
他にも色々とKiroにアドバイスをいただき、requirements.mdが作られました。

.
├── main.tf
└── .kiro
  ├── settings
  │ └── mcp.json
  ├── specs                                   <- new!
  │ └── terraform-infrastructure-enhancement  <- new!
  │   └── requirements.md                     <- new!
  └── steering      
    └── language.md

今回はシンプルな環境で検証したいので、Kiroのアドバイスは無視します。

それでは、作成されたrequirements.md(要件定義書)を確認します。

# 要件定義書
## はじめに
現在のTerraformインフラ構成にタグ付与ルールを適用するための機能です。ステアリングルールで定義された必須タグ(ManagedBy: Terraform、Project: Kiro-test)をすべてのAWSリソースに自動的に適用します。

## 要件
### 要件1: タグ付与ルールの適用
**ユーザーストーリー:** インフラ管理者として、すべてのAWSリソースに統一されたタグが自動的に付与されるようにしたい。これにより、リソースの管理と追跡が容易になる。
#### 受け入れ基準
1. WHEN Terraformリソースが作成される THEN システムは ManagedBy="Terraform" タグを自動的に付与する
2. WHEN Terraformリソースが作成される THEN システムは Project="Kiro-test" タグを自動的に付与する
3. WHEN プロバイダーレベルでdefault_tagsが設定される THEN すべてのリソースに共通タグが適用される
4. WHEN 個別リソースに追加タグが必要な場合 THEN 共通タグとマージして適用される

requirements.mdでは、既存のコードに対してKiroが加える要件の内容が記載されています。
既存コードの内容は無いですね。

さらにテスト要件も伝えました。

この内容で次のフェーズ(design.md(技術設計書)の作成) に進もうと思います。

技術設計書には、既存コードの内容も含まれていてほしいです。

技術設計フェーズ

design.md(技術設計書)の作成をお願いしました。

design.mdが作られました。

.
├── main.tf
└── .kiro
  ├── settings
  │ └── mcp.json
  ├── specs                                   
  │ └── terraform-infrastructure-enhancement  
  │   ├── requirements.md                     
  |   └── design.md        <- new!
  └── steering      
    └── language.md

確認してみると、こちらは既存コードの内容が入っていました!

アーキテクチャの情報やタグ付け戦略、テスト戦略などが欲しい情報が記載されていて、満足できる出来栄えでした!

# 設計文書

## 概要
現在のTerraformインフラ構成にタグ付与ルールを適用するための設計です。
ステアリングルールで定義された必須タグ(ManagedBy: Terraform、Project: Kiro-test)
をすべてのAWSリソースに自動的に適用し、リソース管理の一貫性と追跡可能性を向上させます。

## アーキテクチャ
### 現在の構成分析
現在のmain.tfファイルには以下のリソースが定義されています:
- VPC(aws_vpc.vpc)
- インターネットゲートウェイ(aws_internet_gateway.igw)
- パブリックサブネット(aws_subnet.public_subnet)
- ルートテーブル(aws_route_table.public_route)
- ルートテーブル関連付け(aws_route_table_association.public_route_association)
- セキュリティグループ(aws_security_group.web_sg)
- セキュリティグループルール(aws_vpc_security_group_ingress_rule、aws_vpc_security_group_egress_rule)
- IAMロール(aws_iam_role.ssm_role)
- IAMロールポリシーアタッチメント(aws_iam_role_policy_attachment.ssm_attach)
- IAMインスタンスプロファイル(aws_iam_instance_profile.ssm_profile)
- EC2インスタンス(aws_instance.web_instance)

### タグ付与戦略
#### 1. プロバイダーレベルでのデフォルトタグ設定
```hcl
provider "aws" {
  region = "ap-northeast-1"
  profile = "inaba"
  default_tags {
    tags = {
      ManagedBy = "Terraform"
      Project = "Kiro-test"
    }
  }
}
```

#### 2. ローカル変数での共通タグ定義
```hcl
locals {
  common_tags = {
    ManagedBy = "Terraform"
    Project = "Kiro-test"
  }
}
```

## コンポーネントと インターフェース
### 1. タグ管理コンポーネント
**目的**: 全リソースに統一されたタグを適用する
**実装方法**:
- プロバイダーレベルでのdefault_tags設定
- localsブロックでの共通タグ定義
- 個別リソースでの追加タグ対応

### 2. リソース識別コンポーネント
**目的**: 各リソースに適切な名前とタグを付与する
**実装方法**:
- 既存リソースへのNameタグ追加
- リソース種別に応じた追加タグの設定

### 3. テスト自動化コンポーネント
**目的**: インフラの動作とセキュリティを自動的に検証する
**実装方法**:
- Bashスクリプトによるテスト自動化
- AWS CLIを使用したリソース状態確認
- curlコマンドによるWebサーバー動作確認
- nmapによるポートスキャン
- Checkovによるセキュリティスキャン

### 4. セキュリティ検証コンポーネント
**目的**: IPアドレス制限とSSM接続を検証する
**実装方法**:
- 複数IPアドレスからのアクセステスト
- セッションマネージャー接続テスト
- セキュリティグループルールの動作確認

## データモデル
### タグデータ構造
```hcl
# 必須タグ(全リソース共通)
common_tags = {
  ManagedBy = "Terraform" # 固定値
  Project = "Kiro-test" # 固定値
}

# リソース固有タグ(例)
resource_specific_tags = {
  Name = "リソース名"
  Environment = "dev"
  Component = "web-server"
}

# 最終的なタグ(マージ結果)
final_tags = merge(local.common_tags, local.resource_specific_tags)
```

## エラーハンドリング
### 1. タグ適用失敗への対応
**問題**: 一部のAWSリソースでタグ適用がサポートされていない場合
**対応**:
- Terraformの警告メッセージを確認
- サポートされていないリソースは文書化
- 代替手段(リソース名での識別など)を検討

### 2. タグ制限への対応
**問題**: AWSのタグ制限(50個まで、キー/値の長さ制限など)
**対応**:
- 必須タグを優先
- 追加タグは必要最小限に抑制
- タグ命名規則の統一

## テスト戦略
### 1. タグ適用確認テスト
**目的**: すべてのリソースに必須タグが適用されているかを確認
**方法**:
```bash
# Terraform planでタグ設定を確認
terraform plan
# AWS CLIでリソースのタグを確認
aws ec2 describe-instances --query 'Reservations[].Instances[].Tags'
aws ec2 describe-vpcs --query 'Vpcs[].Tags'
```

### 2. インフラ動作テスト
**目的**: Terraformで構築したインフラが正しく動作することを確認
**方法**:
```bash
# 構文チェック
terraform validate
# リソース作成確認
terraform plan
terraform apply

# Webサーバー動作確認
curl -I http://[EC2のパブリックIP]
# ネットワーク接続確認
ping [EC2のパブリックIP]
# セッションマネージャー接続確認
aws ssm start-session --target [インスタンスID]
```

### 3. セキュリティテスト
**目的**: セキュリティ設定が正しく機能することを確認
**方法**:
```bash
# IPアドレス制限テスト(許可されたIP)
curl -I http://[EC2のパブリックIP] --interface [許可されたIP]
# IPアドレス制限テスト(拒否されるIP)
curl -I http://[EC2のパブリックIP] --interface [許可されていないIP]
# セキュリティスキャン
checkov -f main.tf
# ポート開放チェック
nmap -p 1-65535 [EC2のパブリックIP]
```

### 4. タグ一貫性テスト
**目的**: プロジェクト全体でタグの一貫性を確認
**方法**:
- 全リソースのタグをエクスポート
- ManagedBy="Terraform"、Project="Kiro-test"の存在確認
- タグ値の正確性確認

## 実装詳細
### Phase 1: プロバイダー設定の更新
- default_tagsをプロバイダーブロックに追加
- 既存の設定を維持しながらタグ機能を追加

### Phase 2: ローカル変数の定義
- common_tagsローカル変数を定義
- 将来の拡張性を考慮した構造

### Phase 3: 個別リソースのタグ設定
- 既存リソースにNameタグを追加
- 必要に応じて追加のタグを設定

### Phase 4: テストスクリプトの作成
- インフラ動作テスト用のスクリプト作成
- セキュリティテスト用のスクリプト作成
- IPアドレス制限テスト用のスクリプト作成
- セッションマネージャー接続テスト用のスクリプト作成

### Phase 5: 検証とテスト実行
- terraform planでの変更内容確認
- 実際のリソースへのタグ適用確認
- インフラ動作テストの実行
- セキュリティテストの実行
- 既存機能の動作確認

## 設計上の考慮事項
### 1. 後方互換性
- 既存のリソース設定を変更せず、タグのみを追加
- インフラの動作に影響を与えない変更

### 2. 拡張性
- 将来的な追加タグに対応できる構造
- 環境別(dev/staging/prod)への対応準備

### 3. 保守性
- タグ定義の一元管理
- 変更時の影響範囲を最小化

### 4. コスト管理
- タグによるリソース使用量の追跡が可能
- プロジェクト別のコスト分析が容易

この設計書でtasks.md(タスクリスト)を作成します。

タスクリストの作成、実行フェーズ

tasks.md(タスクリスト)の作成をお願いしました。

tasks.mdが作られました。

.
├── main.tf
└── .kiro
  ├── settings
  │ └── mcp.json
  ├── specs                                   
  │ └── terraform-infrastructure-enhancement  
  │   ├── requirements.md                     
  |   ├── design.md        
  |   └── tasks.md   <- new!
  └── steering      
    └── language.md

タスクリストが作成され、各タスク毎に実行できるようになってました。

# 実装計画

- [ ] 1. Terraformタグ設定の実装
- プロバイダーレベルでdefault_tagsを設定し、すべてのリソースに必須タグを自動適用する
- localsブロックで共通タグを定義し、保守性を向上させる
- 既存リソースにNameタグを追加し、リソース識別を改善する
-_要件: 1.1, 1.2, 1.3, 1.4_

- [ ] 2. インフラ動作テストスクリプトの作成
- Terraform構文チェックとリソース作成確認のスクリプトを作成する
- Webサーバー動作確認(HTTP応答)のテストスクリプトを作成する
- ネットワーク接続確認のテストスクリプトを作成する
-_要件: 2.1, 2.2, 2.3, 2.4_

- [ ] 3. セキュリティテストスクリプトの作成
- セキュリティグループのポート制限確認スクリプトを作成する
- IPアドレス制限テスト(許可されたIPからのアクセス)スクリプトを作成する
- IPアドレス制限テスト(拒否されるIPからのアクセス)スクリプトを作成する
-_要件: 2.5, 2.7, 2.8_

- [ ] 4. SSM接続テストスクリプトの作成
- セッションマネージャーでのEC2接続確認スクリプトを作成する
- SSMロールとインスタンスプロファイルの動作確認を含める
-_要件: 2.6, 2.9_

- [ ] 5. セキュリティスキャン機能の実装
- Checkovを使用したTerraformコードのセキュリティスキャンスクリプトを作成する
- 高リスク脆弱性の検出と報告機能を実装する
- IAM権限の最小権限原則チェック機能を実装する
-_要件: 3.1, 3.2, 3.3_

- [ ] 6. 暗号化設定確認機能の実装
- EBSボリュームの暗号化設定確認スクリプトを作成する
- リソースの暗号化状態を検証する機能を実装する
-_要件: 3.4_

- [ ] 7. 統合テストスクリプトの作成
- 全テストを順次実行する統合テストスクリプトを作成する
- テスト結果の集約と報告機能を実装する
- テスト失敗時のエラーハンドリングを実装する
-_要件: 2.1-2.9, 3.1-3.4_

- [ ] 8. ドキュメントとREADMEの作成
- テストスクリプトの使用方法を説明するREADMEを作成する
- 各テストの目的と期待結果を文書化する
- トラブルシューティングガイドを作成する
-_要件: 全要件のサポート文書_

これらのタスクをすべて完了すると、下記8つのドキュメントがKiroによって生成されました。

  • README.md : 仕様書
  • TROUBLESHOOTING.md: トラブルシューティングガイド
  • TEST_SPECIFICATIONS.md: 各テストの仕様書
  • TEST_README.md: インフラテスト詳細ガイド
  • INTEGRATED_TEST_README.md: 統合テスト詳細ガイド
  • SECURITY_TEST_README.md: セキュリティテスト詳細ガイド
  • SSM_TEST_README.md: SSMテスト詳細ガイド
  • SECURITY_SCAN_README.md: セキュリティスキャン詳細ガイド

作成された仕様書は長くなってしまうので本稿の最後に記載します。
(その他の仕様書は割愛します。)

他にもテストスクリプトが生成されたので、このスクリプトを使用してテストをしていきます。

テストを実施する

Kiroが作成したテストスクリプトを使用してテストします。
Kiroは下記5つのテストスクリプトを生成しました。

  • test-infrastructure.sh
  • test-security.sh
  • test-ssm.sh
  • test-security-scan.sh
  • test-encryption.sh
また、これらのテストスクリプトをまとめて実行できるように、run-all-tests.shも生成されました。
run-all-tests.shを使用して、まとめてテストしようと思います。
 

まずTerraformでリソースをプロビジョニングします。

// Terraformの初期設定
terraform init
// Terraformをdry runする
terraform plan
// リソースをデプロイする
terraform apply

EC2の立ち上がりやyunのアップデート、Webサーバーの立ち上がりを待つため、120秒ほど待つ

sleep 120

その後テストプログラムを実行します。

export AWS_PROFILE=<プロファイル名>
export AWS_REGION=ap-northeast-1
./run-all-tests.sh

結果が下記になります。

==========================================
Terraform Infrastructure Enhancement
統合テスト開始
==========================================
[INFO] 開始日時: 2025-08-24 00:43:21

==========================================
前提条件チェック
==========================================
[SUCCESS] terraform が利用可能です
[SUCCESS] aws が利用可能です
[SUCCESS] curl が利用可能です
[SUCCESS] jq が利用可能です
[SUCCESS] AWS認証情報が設定されています
[INFO] アカウントID: xxxxxxx
[INFO] ユーザー/ロール: arn:aws:iam::xxxxxxx:user/xxxxx
[SUCCESS] Terraformが初期化されています
[SUCCESS] test-infrastructure.sh が見つかりました
[SUCCESS] test-security.sh が見つかりました
[SUCCESS] test-ssm.sh が見つかりました
[SUCCESS] test-security-scan.sh が見つかりました
[SUCCESS] test-encryption.sh が見つかりました
[SUCCESS] すべての前提条件が満たされています

==========================================
1. インフラ動作テスト実行中...
==========================================
[SUCCESS] インフラ動作テストが完了しました
[SUCCESS] ✅ インフラ動作テスト (実行時間: 25秒)

==========================================
2. セキュリティテスト実行中...
==========================================
[SUCCESS] セキュリティテストが完了しました
[SUCCESS] ✅ セキュリティテスト (実行時間: 21秒)

==========================================
3. SSM接続テスト実行中...
==========================================
[SUCCESS] SSM接続テストが完了しました
[SUCCESS] ✅ SSM接続テスト (実行時間: 15秒)

==========================================
4. セキュリティスキャンテスト実行中...
==========================================
[WARNING] セキュリティスキャンテストで問題が検出されました

==================================
セキュリティスキャン結果サマリー
==================================
総テスト数: 10
成功: 8
失敗: 2

[ERROR] 2 個のテストが失敗しました
⚠️ セキュリティ改善が必要です

詳細なレポートを確認してください:
- security_scan_report.txt
- security_scan_results.json

推奨アクション:
1. 高リスク脆弱性を優先的に修正
2. セキュリティグループのCIDR制限を見直し
3. EBSボリュームの暗号化を有効化
4. IAM権限の最小権限原則を確認
[SUCCESS] ✅ セキュリティスキャンテスト (実行時間: 13秒)

==========================================
5. 暗号化設定確認テスト実行中...
==========================================
[ERROR] 暗号化設定確認テストでエラーが発生しました

Terraform設定例:
resource "aws_instance" "example" {
  # ... 他の設定 ...
  root_block_device {
  encrypted = true
  kms_key_id = "alias/aws/ebs" # オプション: カスタムKMSキー
  }
}

==========================================
暗号化設定確認テスト結果
==========================================
総テスト数: 3
成功: 1
失敗: 2
✗ 一部の暗号化テストが失敗しました

暗号化設定確認結果をファイルに保存中...
ℹ 結果がencryption_check_results.txtに保存されました
[ERROR] ❌ 暗号化設定確認テスト (実行時間: 7秒)

==========================================
統合テスト結果レポート生成中...
==========================================
[SUCCESS] 統合テスト結果レポートを integrated_test_report.txt に保存しました

==========================================
統合テスト結果サマリー
==========================================

[INFO] 実行時間: 83秒 (1分23秒)
[INFO] 総テストスイート数: 5
[SUCCESS] 成功: 4
[ERROR] 失敗: 1

[INFO] 詳細結果:
✅ インフラ動作テスト: 成功 (25秒) - Terraform構文チェック、リソース作成確認、ネットワーク接続、Webサーバー動作
✅ セキュリティテスト: 成功 (21秒) - セキュリティグループ設定、IPアドレス制限、ポートアクセス制限
✅ SSM接続テスト: 成功 (15秒) - セッションマネージャー接続、SSMロール・インスタンスプロファイル確認
✅ セキュリティスキャンテスト: 成功 (13秒) - Checkovセキュリティスキャン、IAM権限チェック、脆弱性検出
❌ 暗号化設定確認テスト: 失敗 (7秒) - EBSボリューム暗号化、アカウントレベル暗号化設定

[ERROR] ⚠️ 1 個のテストスイートで問題が検出されました

[INFO] 詳細は integrated_test_report.txt を確認してください

色々と指定されていますね。
EBSボリュームの暗号化が有効化されていないので、色々とエラーが出ているように見えます。

このようにTerraformで作成したリソースをテストすることができました!

Agent Hooksを試す

Agent HooksはKiroで特定のイベント(ファイルの新規作成、保存、削除)が発生したとき、設定したアクションを実行するトリガーです。

Terraformコードが更新されたとき、セキュリティ的な問題が無いかチェックする設定の作成をお願いしました。

KiroのIDEからAgent Hooksを追加します。
Agent Hooksの設定画面が出るので、Describe a hook using natural languageの欄に下記のプロンプトを記載しました。
するとKiroが動き、Hooksファイルを作成してくれます。

Terraformのファイルの更新時、以下の問題がないかチェックするAgent Hooks作成してください。
- 認証情報のハードコーディング
- セキュリティグループのインバウンドルールで0.0.0.0/0を開放
問題があれば、chatを開き問題の場所と修正案を提示してください

プロジェクトフォルダの.kiroディレクトリ内にHooks用のディレクトリが作成され、その中にHooksファイルができていました。

.
├── main.tf
└── .kiro
  ├── settings
  │ └── mcp.json
  ├── specs 
  │ └── terraform-infrastructure-enhancement 
  │   └── requirements.md 
  ├── steering      
  │ ├── language.md 
  │ └── tag-rules.md
  └── hooks                           <- new!
    └── terraform-security-check.json <- new!
こちらはjsonファイルで作成されました。
terraformのファイルが更新されたとき、エージェントがこのプロンプトを入力、実行してくれるみたいですね。
内容はシンプルで分かりやすいですね!
{
  "enabled": true,
  "name":"Terraform セキュリティチェック",
  "description":"Terraformファイルの更新時に認証情報のハードコーディングとセキュリティグループの0.0.0.0/0開放をチェックし、問題があればチャットで修正案を提示します",
  "version":"1",
  "when":{
    "type":"fileEdited",
    "patterns":[
      "*.tf",
      "*.tfvars",
      "*.terraform"
    ]
  },
  "then":{
  "type":"askAgent",
  "prompt":
    "Terraformファイルが更新されました。以下のセキュリティ問題をチェックしてください:\n\n
    1. **認証情報のハードコーディング**\n
    - AWS Access Key、Secret Key\n 
    - パスワード、APIキー\n 
    - データベース接続文字列\n 
    - その他の機密情報\n\n
    2. **セキュリティグループのインバウンドルール**\n 
    - 0.0.0.0/0からのアクセス許可\n 
    - 不適切なポート開放\n 
    - 過度に緩いアクセス制御\n\n
    問題を発見した場合は、以下の形式でチャットを開いて報告してください:\n
    - 問題の場所(ファイル名と行番号)\n
    - 具体的な問題内容\n
    - 推奨される修正案\n
    - セキュリティリスクの説明\n\n
    問題がない場合は、「セキュリティチェック完了:問題は検出されませんでした」と報告してください。"
  }
}

Terraformコードのセキュリティグループを変更して、インバウンドルールの0.0.0.0/0を開放してみます(下記図の54行目)。

 

すると、Kiroによってインバウンドルールで0.0.0.0/0が空いていること検出されました!

最後に

初めてKiroを触りましたが、想像以上にドキュメントを作成してくれるのですごいなと思いました。
Terraformのテストの方法で悩んでいたので、checkovなどのツールを知れたのも良かったです。

Specsモードは当然ですが、Agent SteeringやAgent Hooksなどの各機能も便利で、引き続きKiro触って行きたいなと思います。
記事を書いている間にKiroのプレビュー版が終わって慌てましたが、無事書き終えられてよかったです。

作成された仕様書

# Terraform Infrastructure Enhancement プロジェクト
## 概要
このプロジェクトは、Terraformで構築したAWSインフラストラクチャに対して、統一されたタグ付与ルールの適用と包括的なテスト機能を提供します。

## 主な機能
- **統一タグ付与**: すべてのAWSリソースに必須タグ(ManagedBy: Terraform、Project: Kiro-test)を自動適用
- **インフラ動作テスト**: Terraformで構築したインフラの動作確認
- **セキュリティテスト**: セキュリティグループ設定とIPアドレス制限の検証
- **SSM接続テスト**: セッションマネージャーによるEC2接続確認
- **セキュリティスキャン**: Checkovを使用したセキュリティ脆弱性検出
- **暗号化設定確認**: EBSボリュームなどの暗号化状態検証
- **統合テスト**: 全テストスイートの自動実行と結果集約

## プロジェクト構成
```
.
├── README.md # このファイル
├── main.tf # Terraformメイン設定
├── outputs.tf # Terraform出力定義
├── run-all-tests.sh # 統合テストスクリプト
├── test-infrastructure.sh # インフラ動作テスト
├── test-security.sh # セキュリティテスト
├── test-ssm.sh # SSM接続テスト
├── test-security-scan.sh # セキュリティスキャンテスト
├── test-encryption.sh # 暗号化設定確認テスト
├── test-network-detailed.sh # 詳細ネットワークテスト
├── .kiro/
│ ├── specs/terraform-infrastructure-enhancement/
│ │ ├── requirements.md # 要件定義書
│ │ ├── design.md # 設計文書
│ │ └── tasks.md # 実装計画
│ └── steering/
│   ├── tag-rules.md # タグ付与ルール
│   └── language.md # 日本語コミュニケーションガイド
└── 各種READMEファイル/
  ├── TEST_README.md # インフラテスト詳細ガイド
  ├── INTEGRATED_TEST_README.md # 統合テスト詳細ガイド
  ├── SECURITY_TEST_README.md # セキュリティテスト詳細ガイド
  ├── SSM_TEST_README.md # SSMテスト詳細ガイド
  └── SECURITY_SCAN_README.md # セキュリティスキャン詳細ガイド
```

## 前提条件
### 必要なツール
以下のツールがインストールされている必要があります:
- **Terraform** (>= 1.0)
- **AWS CLI** (>= 2.0) - 認証情報設定済み
- **jq** - JSON処理用
- **curl** - HTTP通信用
- **nmap** - ポートスキャン用(オプション)
- **Checkov** - セキュリティスキャン用
### インストール方法(macOS)
```bash
# Homebrew経由でのインストール
brew install terraform awscli jq curl nmap
# Checkovのインストール
brew install checkov
# または
pipx install checkov
```

### AWS認証情報の設定
```bash
# AWS CLIプロファイルの設定
aws configure --profile inaba
# または環境変数での設定
export AWS_PROFILE=inaba
export AWS_REGION=ap-northeast-1
```

## クイックスタート
### 1. インフラのデプロイ
```bash
# Terraformの初期化
terraform init
# プランの確認
terraform plan
# インフラのデプロイ
terraform apply
```

### 2. 統合テストの実行
```bash
# 全テストスイートを実行
./run-all-tests.sh
```

### 3. 個別テストの実行
```bash
# インフラ動作テスト
./test-infrastructure.sh
# セキュリティテスト
./test-security.sh
# SSM接続テスト
./test-ssm.sh
# セキュリティスキャ
./test-security-scan.sh
# 暗号化設定確認
./test-encryption.sh
```

## テストスイート詳細
### 1. インフラ動作テスト (`test-infrastructure.sh`)
**目的**: Terraformで構築したインフラの基本動作を確認
**テスト項目**:
- Terraform構文チェック
- リソース作成確認
- Webサーバー動作確認(HTTP応答)
**期待結果**: すべてのリソースが正常に動作し、Webサーバーが「hello world」を返す

### 2. セキュリティテスト (`test-security.sh`)
**目的**: セキュリティグループ設定とアクセス制限を検証
**テスト項目**:
- セキュリティグループのポート制限確認
- 許可されたIPアドレスからのアクセステスト
- 拒否されるIPアドレスからのアクセステスト
- 危険ポートの開放チェック
**期待結果**: 適切なアクセス制限が機能し、不要なポートが開放されていない

### 3. SSM接続テスト (`test-ssm.sh`)
**目的**: セッションマネージャーによるEC2接続を確認
**テスト項目**:
- EC2インスタンスの状態確認
- SSMエージェントの接続状態確認
- IAMロールとポリシーの確認
- セッションマネージャー接続テスト
**期待結果**: SSM経由でEC2インスタンスに接続可能

### 4. セキュリティスキャンテスト (`test-security-scan.sh`)
**目的**: Checkovを使用したセキュリティ脆弱性の検出
**テスト項目**:
- 基本セキュリティスキャン
- 高リスク脆弱性検出
- IAM最小権限原則チェック
- セキュリティグループ設定検証
**期待結果**: 高リスクの脆弱性が検出されない

### 5. 暗号化設定確認テスト (`test-encryption.sh`)
**目的**: リソースの暗号化状態を検証
**テスト項目**:
- EBSボリュームの暗号化設定確認
- アカウントレベルの暗号化設定確認
**期待結果**: 適切な暗号化設定が有効になっている

### 6. 統合テスト (`run-all-tests.sh`)
**目的**: 全テストスイートを順次実行し、結果を集約
**機能**:
- 前提条件チェック
- 全テストスイートの順次実行
- 結果の集約と報告
- エラーハンドリング
**期待結果**: すべてのテストスイートが成功し、包括的なレポートが生成される

## 出力ファイル
テスト実行後、以下のファイルが生成されます:
- `integrated_test_report.txt` - 統合テスト結果の包括的なレポート
- `security_scan_results.json` - Checkovセキュリティスキャンの詳細結果
- `security_scan_report.txt` - セキュリティスキャンの要約レポート
- `encryption_check_results.txt` - 暗号化設定確認の詳細結果
- `iam_check_results.txt` - IAM権限チェックの結果
- `sg_check_results.txt` - セキュリティグループチェックの結果

## 要件対応表
| 要件ID | 要件内容 | 対応テストスクリプト |
|--------|----------|---------------------|
| 1.1-1.4 | タグ付与ルールの適用 | main.tf(実装済み) |
| 2.1 | Terraform構文チェック | test-infrastructure.sh |
| 2.2 | リソース作成確認 | test-infrastructure.sh |
| 2.3 | Webサーバー動作確認 | test-infrastructure.sh |
| 2.5 | セキュリティグループポート制限 | test-security.sh |
| 2.6 | SSM接続確認 | test-ssm.sh |
| 2.7 | 許可IPアドレスアクセス | test-security.sh |
| 2.8 | 拒否IPアドレスアクセス | test-security.sh |
| 2.9 | セッションマネージャー接続 | test-ssm.sh |
| 3.1 | セキュリティスキャン実行 | test-security-scan.sh |
| 3.2 | 高リスク脆弱性検出 | test-security-scan.sh |
| 3.3 | IAM最小権限原則チェック | test-security-scan.sh |
| 3.4 | 暗号化設定確認 | test-encryption.sh |

## トラブルシューティングガイド
### よくある問題と解決方法
#### 1. AWS認証エラー
**問題**:
```
Unable to locate credentials. You can configure credentials by running "aws configure"
```
**解決方法**:
```bash
# AWS CLIの認証情報を設定
aws configure --profile inaba

# または環境変数で設定
export AWS_PROFILE=inaba
export AWS_ACCESS_KEY_ID=your-access-key
export AWS_SECRET_ACCESS_KEY=your-secret-key
export AWS_REGION=ap-northeast-1

# 認証情報の確認
aws sts get-caller-identity
```

#### 2. Terraformの初期化エラー
**問題**:
```
Error: Backend initialization required
```
**解決方法**:
```bash
# Terraformの初期化
terraform init

# プロバイダーの更新が必要な場合
terraform init -upgrade
```

#### 3. EC2インスタンスが見つからない
**問題**:
```
実行中のEC2インスタンスが見つかりません
```
**解決方法**:
```bash
# Terraformでインフラを構築
terraform plan
terraform apply

# インスタンスの状態を確認
aws ec2 describe-instances --filters "Name=tag:Name,Values=kiro-test-web-instance"

# Terraformの状態確認
terraform show
```

#### 4. HTTPアクセスが失敗する
**問題**:
```
HTTPアクセスが失敗しました
```
**原因と解決方法**:
**原因1**: EC2インスタンスが起動中
```bash
# インスタンスの状態確認
aws ec2 describe-instances --instance-ids $(terraform output -raw instance_id)
# 解決方法: 1-2分待ってから再実行
```
**原因2**: セキュリティグループの設定問題
```bash
# セキュリティグループの確認
aws ec2 describe-security-groups --group-ids $(terraform output -raw security_group_id)

# 解決方法: main.tfのセキュリティグループ設定を確認
```
**原因3**: Webサーバー(nginx)が起動していない
```bash
# SSMでインスタンスに接続してnginx状態確認
aws ssm start-session --target $(terraform output -raw instance_id)
sudo systemctl status nginx
sudo systemctl start nginx # 必要に応じて起動
```

#### 5. SSM接続が失敗する
**問題**:
```
SSMエージェントがオンラインではありません
```
**解決方法**:
```bash
# インスタンスの起動から数分待つ
sleep 120
# SSMエージェントの状態確認(インスタンス内で実行)
sudo systemctl status amazon-ssm-agent
sudo systemctl restart amazon-ssm-agent
# IAMロールの確認
aws iam get-role --role-name $(terraform output -raw iam_role_name)
aws iam list-attached-role-policies --role-name $(terraform output -raw iam_role_name)
```

#### 6. Checkovのインストールエラー
**問題**:
```
externally-managed-environment
```
**解決方法**:
```bash
# Homebrewを使用(推奨)
brew install checkov
# または pipx を使用
brew install pipx
pipx install checkov
# pipxのパスを追加
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
```

#### 7. jqコマンドが見つからない
**問題**:
```
jq: command not found
```
**解決方法**:
```bash
# macOSの場合
brew install jq
# Linuxの場合
sudo apt-get install jq # Ubuntu/Debian
sudo yum install jq # CentOS/RHEL
```

#### 8. nmapが利用できない
**問題**:
```
nmapが利用できないため、ポートスキャンをスキップします
```
**解決方法**:
```bash
# macOSの場合
brew install nmap
# Linuxの場合
sudo apt-get install nmap # Ubuntu/Debian
sudo yum install nmap # CentOS/RHEL
```

#### 9. パブリックIPアドレスが取得できない
**問題**:
```
パブリックIPアドレスを取得できませんでした
```
**解決方法**:
```bash
# Terraformのoutput確認
terraform output
# outputs.tfファイルの確認
cat outputs.tf
# 必要に応じてoutputを追加
terraform apply
```

#### 10. セキュリティスキャンで多数の警告
**問題**:
```
多数のセキュリティ警告が検出されました
```
**対応方法**:
**高リスク問題の優先対応**:
- CKV_AWS_260: セキュリティグループの0.0.0.0/0制限
- CKV_AWS_8: EBSボリューム暗号化
- CKV_AWS_79: EC2メタデータサービスv2強制
**設定例**:
```hcl
# セキュリティグループの制限
resource "aws_vpc_security_group_ingress_rule" "allow_http_rule" {
  security_group_id = aws_security_group.web_sg.id
  cidr_ipv4 = "x.x.x.x/32" # 特定IPのみ
  from_port = 80
  ip_protocol = "tcp"
  to_port = 80
  description = "Allow HTTP from office IP"
}

# EBSボリューム暗号化
resource "aws_instance" "web_instance" {
  # ... 他の設定 ...
  root_block_device {
    encrypted = true
  }
  # メタデータサービスv2強制
  metadata_options {
    http_tokens = "required"
  }
}
```

### デバッグのためのコマンド 
#### Terraformの状態確認
```bash
# 現在の状態表示
terraform show
# 特定リソースの状態確認
terraform state show aws_instance.web_instance
# 出力値の確認
terraform output
```

#### AWSリソースの直接確認
```bash
# EC2インスタンス一覧
aws ec2 describe-instances --filters "Name=tag:Project,Values=Kiro-test"
# セキュリティグループ一覧
aws ec2 describe-security-groups --filters "Name=tag:Project,Values=Kiro-test"
# VPC一覧
aws ec2 describe-vpcs --filters "Name=tag:Project,Values=Kiro-test"
# SSM管理対象インスタンス一覧
aws ssm describe-instance-information
```

#### ログファイルの確認
```bash
# 統合テストレポート
cat integrated_test_report.txt
# セキュリティスキャン結果
cat security_scan_report.txt
# 暗号化チェック結果
cat encryption_check_results.txt
```

## パフォーマンス最適化
### テスト実行時間の短縮
1. **並列実行**: 独立したテストは並列で実行可能
2. **キャッシュ活用**: Terraformプランのキャッシュを活用
3. **条件分岐**: 不要なテストをスキップする条件を追加
### リソース使用量の最適化
1. **インスタンスタイプ**: 開発環境では小さなインスタンスタイプを使用
2. **自動停止**: テスト完了後のリソース自動停止
3. **スポットインスタンス**: コスト削減のためのスポットインスタンス活用
## セキュリティベストプラクティス
### 1. アクセス制限
- セキュリティグループで必要最小限のポートのみ開放
- 特定IPアドレスからのアクセスに制限
- WAF(Web Application Firewall)の導入検討
### 2. 暗号化
- 転送時暗号化(HTTPS)の使用
### 3. 監査とログ
- CloudTrailによるAPI呼び出しログ
- VPCフローログによるネットワーク監視
- CloudWatchによるメトリクス監視
### 4. IAM権限
- 最小権限の原則に従った権限設定
- マネージドポリシーの活用
- 定期的な権限レビュー
## CI/CDパイプライン統合
### GitHub Actions例
```yaml
name: Infrastructure Tests
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 9 * * 1' # 毎週月曜日9時
  jobs:
    terraform-tests:
      runs-on: ubuntu-latest
      steps:
        - name: Checkout
          uses: actions/checkout@v3
        - name: Setup Terraform
          uses: hashicorp/setup-terraform@v2
          with:
            terraform_version: 1.5.0
        - name: Configure AWS credentials
          uses: aws-actions/configure-aws-credentials@v2
          with:
            aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
            aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
            aws-region: ap-northeast-1

        - name: Install dependencies
          run: |
            sudo apt-get update
            sudo apt-get install -y jq curl nmap
            pip install checkov

        - name: Terraform Init
          run: terraform init

        - name: Run integrated tests
          run: ./run-all-tests.sh

        - name: Upload test results
          uses: actions/upload-artifact@v3
          if: always()
          with:
            name: test-results
              path: |
                integrated_test_report.txt
                security_scan_results.json
                security_scan_report.txt
```

## 継続的改善
### 1. テストカバレッジの拡張
- パフォーマンステストの追加
- 負荷テストの実装
- 災害復旧テストの追加
### 2. 自動化の強化
- テスト結果の自動通知
- 失敗時の自動ロールバック
- 定期的なセキュリティスキャン
### 3. 監視とアラート
- CloudWatchアラームの設定
- SNS通知の設定
- ダッシュボードの作成
## サポートとコミュニティ
### ドキュメント
- [Terraform公式ドキュメント](https://www.terraform.io/docs)
- [AWS CLI公式ドキュメント](https://docs.aws.amazon.com/cli/)
- [Checkov公式ドキュメント](https://www.checkov.io/)
### 問題報告
問題が発生した場合は、以下の情報を含めて報告してください:
1. 実行環境(OS、ツールバージョン)
2. エラーメッセージの全文
3. 実行したコマンド
4. 生成されたログファイル
### 更新履歴
- v1.0.0: 初回リリース - 基本的なタグ付与とテスト機能
- 今後の予定:
- パフォーマンステストの追加
- 並列実行サポート
- カスタムテストスイートの追加機能
- Terraformモジュール化
---

**注意**: このプロジェクトはAWSリソースを作成するため、AWS料金が発生する可能性があります。テスト完了後は不要なリソースを削除してください(`terraform destroy`)。
タイトルとURLをコピーしました