
はじめに
Kiro University Challenge に参加して、AWS が公開している IP レンジ一覧をターミナル上で絞り込み・閲覧できる TUI アプリ AWS Public IP Ranges Navigator を作りました。
このチャレンジは 2026 年 9 月 21 日〜25 日にかけて毎日レッスンが公開され、学んだことを 1 つのプロジェクトに落とし込んで最終課題(Take-home final exam)として10 月 5 日までに提出する、というプログラムです。
採点は「7 つのレッスンで学んだ内容を、提出プロジェクトでどれだけ実演できているか」で決まります。
この記事では、何を作ったのか、そして Kiro をどう使って作ったのかを振り返ります。
作ったもの
AWS は自社の公開 IP レンジを ip-ranges.amazonaws.com/ip-ranges.json で JSON として公開しています。
この一覧を、キーボード操作だけでリージョン・サービスごとに絞り込んで眺められるようにしたのが今回のアプリです。
TUI フレームワークには Textual を採用しました。

主な機能
- 起動時に HTTPS で最新の IP レンジ文書を取得(タイムアウトは 15 秒)
- 3 ペイン構成:左に Region リストと Service リスト、右に結果テーブル、下部にキーバー
- Region・Service のどちらか、または両方で絞り込み。各リスト先頭の
ALLは「絞り込みなし」 - 結果テーブルには連番・CIDR・Region・Service を表示し、ヘッダーに一致件数をライブ表示
- アプリを終了せずにデータを再取得(
rキー)し、取得・パースは UI スレッド外で実行するので画面は固まらない - 取得・パースに失敗しても既存データは保持し、非ブロッキングのメッセージを出してそのまま動き続ける
- マウス操作にも対応(クリックで選択、ホイールでスクロール)
キーボード操作
| キー | 動作 |
|---|---|
↑ / ↓ |
アクティブなリスト内で選択を移動 |
Tab |
Region リストと Service リストの切り替え |
x |
フィルターをクリア(両リストを ALL に戻す) |
r |
IP レンジ文書を再取得 |
q |
終了 |
Kiro をどう使ったか
今回いちばん意識したのは、Kiro の Spec 駆動開発をきちんと回すことでした。
いきなりコードを書き始めるのではなく、requirements → design → tasks の 3 ステップを
順番に固めてから実装に入ります。
成果物は .kiro/specs/ 配下に残ります。
1. Requirements(要件定義)
まず、KiroのSpecモードで EARS 記法に近い形で受け入れ基準を書き出します。
たとえば「起動時に HTTPS でデータを取得する」「15 秒以内に文書を受け取れなければ取得を中止してエラーを表示し、アプリは動き続ける」といった条件を、あいまいさが残らないよう 1 つずつ列挙しています。
最終的に 12 個の Requirement と、それぞれの Acceptance Criteria にまとまりました。
用語も Glossary として先に定義されます。
Data_Fetcher、Data_Store、IP_Prefix、Active_Panel のように名前を決めておくと、以降の設計・実装で表現がぶれません。

2. Design(設計)
設計では、バグが出やすいロジックを純粋関数として切り出します。
レイヤーは次のように分けています。
- ネットワーク層 (
fetcher):HTTPS 取得とタイムアウトだけを担当する I/O - パース層 (
parser):JSON をIP_Prefixに変換。壊れた文書・プレフィックス欠如・ 個々のエントリ不正を区別して扱う - ドメイン層 (
store/filtering/navigation/models):状態保持と絞り込み計算。 すべて副作用のない純粋関数 - プレゼンテーション層 (
app):Textual による描画と入力ルーティング
この分け方のおかげで、いちばん壊れやすいパースと絞り込みのロジックを、UI から切り離して単体で徹底的にテストできます。
フレームワークに Textual を選んだ理由(DataTable・ListView・Footer などが要件にそのまま対応する)や、curses を見送った理由も設計書に残し、判断の根拠を後から追えるようになっています。
さらに設計書では「正しさのプロパティ(Correctness Properties)」が 17 個定義されました。
たとえば「有効なエントリを文書化してパースし直すと元と等価になる(ラウンドトリップ)」
「絞り込み結果はヘッダーの件数と必ず一致する」といった、全入力にわたって成り立つべき性質です。
これがそのまま後のプロパティベーステストの仕様になります。

3. Tasks(実装計画)
実装は「純粋なコア → I/O → プレゼンテーション → エントリポイント → パッケージング」の
順に進むよう、タスクが並べられます。
各タスクは対応する Requirement と Property を明記してトレーサビリティを確保し、依存関係を wave として整理しています。テストを書くサブタスクは* 付きの任意扱いにして、MVP を優先できる構成にしました。

Steering でコーディング規約を固定
.kiro/steering/python-guidelines.md にプロジェクト共通の Python 規約を置き、Kiro が生成するコードを常にその方針に沿わせました。
主なルールは次のとおりです。
- PEP 8 準拠、4 スペースインデント、1 行 88〜99 文字
- 構造化データは
@dataclass、不変にすべきものはfrozen=True - 素の
except Exception:で握りつぶさず、専用の例外クラスに整理して型で分岐 with/try-finallyで後始末を保証
実際、IP_Prefix は frozen=True の dataclass にし、例外は NavigatorError を頂点とする
階層(FetchError / FetchTimeoutError / ParseError など)に整理されています。
Steering を効かせることで、こうした方針が全モジュールで一貫しました。

品質はプロパティベーステストで担保
純粋関数として切り出したロジックには、Hypothesis によるプロパティベーステストを当てました。
具体例を 1 つずつ書くのではなく、「どんな入力でもこの性質が成り立つ」ことを大量の自動生成ケースで検証します。
設計時に定義した 17 個のプロパティが、そのままテストの指針になりました。
- パースのラウンドトリップと、不正エントリのスキップ
ALL/ 特定値のあらゆる組み合わせでの絞り込みの正しさ- 件数と表示行数の一致、連番のギャップなし
- 選択インデックスのクランプ、スクロールしても選択が変わらない不変性
UI(app)は Textual の run_test を使った結合テストで、起動・フォーカス移動・リロード・終了・マウス操作を検証しました。

振り返って
Spec 駆動で進めてよかったのは、「何を作るか」で迷う時間がほぼなくなったことです。
要件と設計を先に固めておくと、実装フェーズは決めたことを形にするだけになり、Kiro に任せる範囲も明確になります。
設計書に「なぜこの技術を選んだか」まで残しているので、後から見返しても判断の背景がすぐ分かります。
Textual という普段触れる機会が少ないフレームワークでも、要件との対応づけを設計段階で済ませていたおかげで詰まりが少なく済みました。
チャレンジのレッスンで勧められていた「まだ使ったことのない Kiro の機能を試す」という趣旨にも沿って、いつもと違う進め方を試せたのが収穫でした。
その他、Powers や Custom Agents なども作成しています。
また、提出物のデモ動画が必要になりますが、そこも Kiro に依頼することで簡単に gif 形式で作成ができました。
おわりに
AWS Public IP Ranges Navigator は、実用的な小さなツールでありながら、Spec 駆動開発・Steering による規約統一・プロパティベーステストという、Kiro を使った開発の型をひととおり実践できる題材になりました。
同じチャレンジに挑む人の参考になればうれしいです。
使い方(おまけ)
python -m venv .venv source .venv/bin/activate pip install -e . python -m aws_ip_navigator
起動後は ↑ / ↓ で選択、Tab でリスト切り替え、x でフィルタークリア、
r で再取得、q で終了です。























































































