新春早々、[VibeCoding100]というバイブコーディングモノづくり100連発企画を思いついて筆を執っています。もちろんソフトウェアエンジニアリングすごい人たちからは「バイブコーディングってのはアレだよね…」みたいな苦言もいただくことは100も承知です。やれ設計ができないとか一貫性がないとか。まあでも実際これぐらいコード書くようになると、視界が変わってくるってことをまずはお伝えしたいです。
主に使っているコーディングエージェントはClaude, Codex, Geminiです(ぜんぶ?)。VSCodeを使っています。CursorとかAntigravitiyとかも、もちろん使って評価していますが、好かない…というか、実用性や、プロの仕事、チームの仕事としての後方互換性もとても重要ですので簡単にエディターを乗り換えません(いまだにvim派です)。驚き屋をするためにコーディングエージェント使う人もいるかもしれないけど、自分のスタンスとしては「技術で食っていかねばならない経営視点+研究開発視点+人を育てる教育者視点もあるフルスタック技術者」という視点でご笑納いただければ幸いです。
前置きが長くなってしまいましたが、記念すべき第1回の価値は約51万円。
しかも、いっさいコードを書きません。
題して…
[VibeCoding100] #1 AIバイブコーディングで最初にやるべきことは「片付けろ!!」AWSコストダウンopsで金鉱脈を掘る!! です。
正月らしく景気いいな
目的:開発中に生まれたAWS上の不要なリソースを全撤去
コードを書きませんが、コスト効果は絶大でした。
実施前
削れるものは削った状態のAWSです。
| サービス | 月額 (USD) |
|---|---|
| EC2 Compute | $237 |
| RDS | $165 |
| EC2 - Other | $151 |
| Tax | $70 |
| Directory Service | $57 |
| ELB | $32 |
| VPC | $26 |
| その他 | $59 |
| 合計 | $797/月 |
"削れるものは削ったはず"なのに…月額$797×12=$95641USD=155JPYで…年間コスト: 約148万円!!!
実施後
放置しようと思って放置していたわけではなく、本当に「見つけられなかった開発時の残骸」なのです。
新しい月額: 約$522/月(約97万円/年)
なぜAIエージェントが必要だったのか - 多すぎるAWSのマイクロサービスとその依存地獄
今回調査対象になったサービスを列挙してみましょう:
- EC2, EBS, VPC, Subnet, Security Group, Elastic IP
- RDS (Aurora PostgreSQL), Secrets Manager
- Directory Service, WorkSpaces
- ELB (ALB), Target Group, Auto Scaling Group
- SageMaker (Domain, UserProfile, App)
- Lightsail, ECR, ECS
- Lambda, API Gateway, Cognito
- S3, DynamoDB, Route53
- CloudWatch (Logs, Metrics, Alarms)
- IAM (Role, Policy, Instance Profile)
- KMS, Amplify, Backup...
これ全部、依存関係がある。
例えば Aurora を消すには:
- まず依存する EC2 を確認
- Secrets Manager のシークレットを確認
- VPC 内のセキュリティグループを確認
- 関連する IAM ロールを確認
Directory Service を消すには:
- WorkSpaces が残っていないか確認
- 関連する VPC/Subnet を確認
- DNS 設定を確認
人間がこれを全部追いかけるのは、正直しんどい。
「全リージョンに横断して調査」が意外と手間
AWS には 20 以上のリージョンがあります。今回見つかった Directory Service は ap-southeast-2(シドニー) にありました。普段使っているのは ap-northeast-1(東京)と us-east-1(バージニア)。GPUインスタンスをステージングするにしても us-east-2とかです。シドニーなんて意識したことない。
でも Cost Explorer を見ると確かにコストが発生している。おそらく依頼した開発者さんの気分で選ばれたか、初心者のミスか、何か「どこでもいいから使ってないリージョンで試してみて」みたいなミッションがあったのでしょう。
どこだ? AWSにはそういう「特定のサービスがどこのリージョンで使われているか」を調べるのが意外と難しいです。「Finding Nemo」じゃあるまいし、行ったこともない P. Sherman, 42 Wallaby Wayを探すようなものです。
# service_inventory.py の一部
REGIONS = [
"ap-south-1", "eu-north-1", "eu-west-3", "eu-west-2", "eu-west-1",
"ap-northeast-3", "ap-northeast-2", "ap-northeast-1", "ca-central-1",
"sa-east-1", "ap-southeast-1", "ap-southeast-2", "eu-central-1",
"us-east-1", "us-east-2", "us-west-1", "us-west-2"
]
for region in REGIONS:
directories = ds_client.describe_directories()
# ...
17リージョン × 20サービス = 340回の API コール...。
これをコマンドライン、手動でやる?無理。
ログを見てもらい利用状況をチェック「このリソース、使われてるの?」
これが一番難しい問いです。存在するだけでは判断できない。
Claude に頼んだのは:
CloudWatch メトリクス(CPU使用率、ネットワーク I/O)
直近30日のコスト
関連するログの有無
### ap-northeast-1 / i-0846924779bd9db5b
- Name: QR-Kakuin
- InstanceType: t2.micro
- State: running
- Metrics (30d):
- CPU avg: 2.66%
- NetworkIn/Out: 240.24 MB / 8.18 MB
CPU 2.66%。動いてはいるけど、ほぼ何もしていない。これはQRコードで角印を作るようなサービスですね。自作した覚えがあります。
Aurora に至っては、とあるハッカソンで作ったdiscord botの残骸が。
SELECT datname, pg_size_pretty(pg_database_size(datname)) as size
FROM pg_database WHERE datistemplate = false;
datname | size
---------------+---------
user_discord | 8143 kB
auth_db | 7935 kB
8MB のデータベースに月額 $165 払ってた!!! 無駄無駄無駄ア!!
パスワードがわからない?無駄無駄無駄ァ!!
でもこの Aurora に接続しようとしたら、パスワードがわからない。まあハッカソン感覚で作ったものだからな、いちおう資料はあるけど調査して確認する時間がない。調べているうちに「情が移る」ことで「まあいっか」ってなってしまう。で、「Auroraのパスワードなんだっけ」ってなる。
AI時代のホワイトハッカーはこんなところで財布の紐を緩めている場合じゃありません。
ここは 土地デベロッパーがダンプカーと解体屋で地上げしていくように、ClaudeをつかってAuroraのパスワードを強制解除していきましょう。
まずAWS には Secrets Manager がある。
aws secretsmanager get-secret-value \
--secret-id "rds!cluster-45385691-fd75-46c5-9717-d0b6ed7f6f16" \
--region ap-southeast-1
ところがこれ、シェルで実行すると ! がヒストリ展開される問題が発生します。
ValidationException: Invalid name. Must be a valid name containing
alphanumeric characters, or any of the following: -/_+=.@!
これを見て Claude Code に 即座に 回避策を提案してもらいます。
ファイル経由で ARN を渡す
echo 'arn:aws:secretsmanager:...:secret:rds!cluster-...' > /tmp/secret_arn.txt
aws secretsmanager get-secret-value --secret-id "$(cat /tmp/secret_arn.txt)"
人間だったら「なんでエラー?」で30分は溶けてた。
ちなみにこの技は、base64などを組み合わせると、直接ログインできないコンテナインスタンスで何か強制解除したり、危ないコードを送りつけるときなんかにも役立ちます(あまり書くと危ない技)。
DBのダンプを行い価値を判断
「消していい?」の判断には、中身を見る必要がある。人間が責任を負わないといけないやつです。
Aurora はプライベートサブネットにあるので直接接続できない。こういう「データベースの3層スキーマできっちりつくる」とか「ロードバランサーでスケールした時もバッチリ」みたいなAWSサービスが、ほんとたくさんある。システム構築の教科書としては正しいんだけど、AIスタートアップのビジネス継続性の視点では「たいしてスケールもしないサービスにこんな値段をかけてサンクコストを垂れ流しにしてはいけません!」ってなります。
"プロの撤退戦"をやらねばならぬ。
まずはSSM Session Manager でポートフォワードを張る
aws ssm start-session \
--target i-08a16175e54a3eacd \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters '{"host":["user-database-dev.cluster-xxx.rds.amazonaws.com"],
"portNumber":["5432"],"localPortNumber":["15432"]}'
接続してダンプ:
pg_dump -h 127.0.0.1 -p 15432 -U username -d user_discord > backup.sql
結果:
COPY public.users (id, discord_user_id, ...) FROM stdin;
\.
-- 0件
COPY public.subscriptions (...) FROM stdin;
\.
-- 0件
ユーザーデータ 0件。開発用スキーマだけ。
これを見て「消していい」と即断できた。
こいつはDB設計としては正しい。
でも、この世に存在してはならないのだ。
私が今ここで、責任を持って、消さねばならないやつ。
とはいえ、人間がやっていたら8時間どころでは終わらない
そんな感じで、何かの並列作業で Claude Code の余り時間を使って GitHub Actions のスクリプトと AGENTS.md を使って、コストオプス(Cost-Ops)を実施していきます。
今回の作業を分解すると:
みっちり張り付いて作業するのではなく、何かの並列作業で1ヶ月ぐらい様子見てました。
以下は、Claude自身に作らせたClaude自身の作業ログから人間がコマンドラインで操作した場合の作業量です。
- Cost Explorer でコスト分析 - 30分
- 全リージョンのリソース棚卸し - 2時間
- 各リソースの依存関係調査 - 2時間
- 利用状況(メトリクス)確認 - 1時間
- DB接続・ダンプ取得 - 1時間(トラブルシューティング含む)
- 削除実行・確認 - 30分
- ドキュメント整備 - 1時間
- 自動化(GitHub Actions)- 1時間
合計推定時間(人間なら): 9時間以上
Claude との対話でやったら 「合計2時間」。
しかも、VSコードを別窓で開いて、時々様子を見て、その都度判断しているだけ。途中で SSM セッションがタイムアウトしたり、シェルの特殊文字問題が起きたり、という「人間だったら心折れる」トラブルも、淡々と対処してくれた。えらいぞClaude。ちなみにAmazonQにもGeminiにもCodexにもこの作業をやらせてみたのだけど…
- AmazonQ: 英語でSlackのインタフェースになってくれるのが嬉しい人には嬉しい
- Codex: 比較的賢い、でもなかなかミッションクリティカルにゴールに辿り着いてくれない。寄り道が多くて、気がついたら仕事が大拡散している。
- Gemini: ログを見たりハッカーとリアルタイムで戦うのは得意。Gemini CLIがそもそも高価なので、この手の緊急ではないログ分析仕事をさせるとAPIコストが気になる。
冷徹でデータに基づく「無に帰せる判断」の重要性
サンクコスト(sunk cost)。人間は「いつか使うかも」と思ってしまう。
一生懸命開発してきたシステムならなおのことです。
そして、開発に関わった職人さんたちは「終わったら忘れたい」と言って、どこかに行ってしまいます。ドキュメントも残ってますが、運用のためのドキュメントに「どうやったら無に帰せるか」は書いてありません。
Claude は違う:小さなサンクコストを見逃さない。
ディレクトリサービスが謎の請求書の真ん中あたりにありました。
作成日: 2023-06-28
削除日: 2026-01-02
期間: 約30ヶ月
月額: $57
累計: $1,710 (約26.5万円)
WorkSpaces: 0件
→ 削除して問題なし
30ヶ月、WorkSpaces 0件で $1,710。
データを見せられたら、人間も決断できる。たぶん、WorkSpacesをセットアップしている間に「$57かあ…高いな…リモートデスクトップでいいや…」ってなった。なったのだけど「どうやって削除するんだっけ?」と調べている時間が勿体なくなった(そして放置)。ディレクトリサービスはその横にいた。
実際にはWorkSpacesの削除は簡単ではなかったこともよくわかった。
継続的な測定に基づく調査
単発の調査では意味がない。来月また同じことが起きる。
例えばインスタンスを潰してもCloudFormationが再構築したりする。
作業の途中で、記憶がなくても、続きができるように。
週次の自動棚卸しを実装しています。
on:
schedule:
- cron: "0 23 * * 0" # 毎週月曜 08:00 JST
毎週月曜の朝、 Slack に通知が来る。コストが増えたら気づける。
後戻りできる方法とログの自動化
「消して大丈夫?」の不安を解消するために、すべての作業をダンプし、バックアップし、元に戻れる方法や解説、判断の過程をログにしている。その証拠にこんなブログ(このブログ)も書ける。
後で「あれ、何を消したんだっけ?」となっても、全部残ってる。
実装したソリューション
1. GitHub Actions による週次棚卸し
# .github/workflows/weekly-inventory.yml
name: weekly inventory
on:
schedule:
- cron: "0 23 * * 0" # Monday 08:00 JST
workflow_dispatch: {}
毎週月曜日に自動でAWSリソースをスキャンし、コストレポートをSlackに通知。
2. AWS CLI によるリソース調査・削除
# Aurora PostgreSQL のダンプ取得
aws ssm start-session \
--target i-08a16175e54a3eacd \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters '{"host":["user-database-dev.cluster-xxx.ap-southeast-1.rds.amazonaws.com"],"portNumber":["5432"],"localPortNumber":["15432"]}'
pg_dump -h 127.0.0.1 -p 15432 -U user -d user_discord > backup.sql
3. エージェント設計ドキュメント (AGENTS.md)
せっかくの初回企画なので AGENTS.md を大公開。もちろんセキュリティ上、大事なところは削ったりしていますが、そのまま使える可能性が高い要素があります。最も大事なところは「エージェント自体を作り出す」という設計です。映画「Matrix」みたいですね!さらにそのエージェントに「エサ」を与えています。シェアやハートも歓迎です。
# AGENTS
このリポジトリは、AWS上の「残骸リソース」(使われていないのに残っている EC2 / SageMaker / DB など)を検出し、
安全にバックアップ・削除するためのエージェント群で構成されています。
## 現在の重点方針(2026-01)
- **SageMaker CodeEditor**: us-west-2 に3ドメイン残存。CDKデプロイ用なら削除可能。
- **名前なしEC2 x2**: ap-northeast-1 の t3a.small x2。用途不明、削除候補。
- Cognito を残し、その他は順次削除。
- タグ運用: `COST-OPS=true`(追跡)、`COST-OPS-DEL-CANDIDATE=true`(削除候補)。
---
## 管理対象プロジェクト一覧(2026-01-01 時点)
### 稼働中 / 要判断
| プロジェクト | リージョン | リソース | 月額概算 | 状態 | 備考 |
|-------------|-----------|---------|---------|------|------|
| SageMaker CodeEditor | us-west-2 | 3ドメイン (CodeEditorStack-AICUjp, rootuser, QuickSetup) | $15 | 要確認 | CDKデプロイ時に作成?GenUではない |
| 名前なしEC2 x2 | ap-northeast-1 | t3a.small x2 | $35 | 削除候補 | CPU 0.1%、用途不明 |
| Lightsail | - | 2インスタンス | $16 | 後で判断 | WordPress用途 |
| Directory Service | - | 1つ | $57 | 要確認 | 用途不明 |
### 調査中 / 未発見
| プロジェクト | 状況 | 次のアクション |
|-------------|------|---------------|
### 削除済み(2025-12)
| プロジェクト | リージョン | 削除日 | 削減額/月 |
|-------------|-----------|-------|----------|
## 全体コンセプト
- 人間の判断を必ず挟む(**勝手に消さない**)
- 消す前に
- コスト削減見込みを提示
- 設定/メタ情報/必要に応じてデータのバックアップ
- ロールバックパス(どうやって戻すか)の記録
- 週次で評価ループを回し、「片肺運転」「残骸候補」を一覧で把握する
- タグ無しのリソースには `COST-OPS=true` を付与して追跡する
主なエージェントは以下です。
- `WeeklyCostEvaluator` … 週次のコスト・ログ評価(マルチリージョン)
- `ZangaiJudge` … 残骸判定(スコア+ステータス)
- `SafeDelete` … バックアップ付き削除フロー
- `DBArchiver` … 「生きていないデータベース」のローカルダウンロード+削除候補化
---
## ステータスとスコア
各リソースは、最低限以下の項目を持ちます。
- `status`(判定ステータス)
- `zangai_score`(残骸スコア、0–100程度)
- `flags`(補助フラグ)
- `deleted` / `deleted_at` / `deleted_by`(削除済みかどうか)
### status
- `ACTIVE`
- ふつうに稼働中。ログもコストも妥当。
- `IDLE`
- 活動頻度が低い。今すぐ消さないが、監視対象。
- `ZANGAI_CANDIDATE_AUTO`
- ログ/コスト/タグから自動で「残骸っぽい」と判定された状態。
- ここではまだ削除ボタンは有効にならない。
- `ZANGAI_CONFIRMED`
- 人間が画面上で確認し、「消していい残骸」と明示的にマークした状態。
- この状態のリソースのみ、削除ボタンが有効になる。
- `BLOCKED_NEEDS_REPO_INFO`
- Cognito / Lambda / DB などで元リポジトリや IaC 情報が特定できない。
- 誤って消すとロールバック不能なため、削除禁止。
- `KEEP`
- 「残骸っぽく見えるが、事情があって残す」。今後の自動判定対象外。
### zangai_score(例)
自動評価のヒントとして、0–100 のスコアをつけます(数値そのものは参考)。
- ログが90日以上出ていない: +50
- 直近30日コスト < 1 USD: +20
- Projectタグに `demo` / `tmp` / `sandbox` などを含む: +20
- prod が存在しないのに dev/stg が別リージョンに残っている: +30
合計 80 以上で `ZANGAI_CANDIDATE_AUTO` など、ルールは `scripts/weekly_evaluate.py` 内で定義します。
---
## WeeklyCostEvaluator(週次コスト評価エージェント)
- 実体
- GitHub Actions: `.github/workflows/weekly-cost-eval.yml`
- ロジック: `scripts/weekly_evaluate.py`
- トリガ
- 毎週 **月曜日 8:00 日本時間**
- GitHub Actions は UTC で動くため、cron は `0 23 * * 0`(日曜 23:00 UTC)
- 入力(Secrets / Env)
- `AWS_ROLE_ARN` : 読み取り専用のコスト評価ロール ARN
- `AWS_REGION` : 代表リージョン(例: `ap-northeast-1`)
- `SLACK_WEBHOOK_URL` : Slack Incoming Webhook URL(通知用)
### 役割
1. `config/regions.yml` に定義された全リージョンをループ
2. EC2 / SageMaker / DB などの主要リソースを列挙
3. CloudWatch Logs / メトリクス・Cost Explorer を参照し、
- 直近7〜30日のログ活動量
- 日次・週次コスト
4. `summary/projects_weekly/YYYY-MM-DD.csv` に「1リソース1行」で出力
5. プロジェクト × 環境(dev/stg/prod) × リージョンのマトリクスを生成し、
- `summary/projects_weekly_matrix/YYYY-MM-DD.csv` に出力
6. 主要な増減・残骸候補を `reports/YYYY/YYYY-MM-DD-weekly.md` にまとめる
7. Slack へ「週次評価完了+サマリ」を通知する
### Multi-Region View(リージョン横断ビュー)
WeeklyCostEvaluator は
- `account_id`
- `project`(タグ `Project`)
- `env`(タグ `Env` = dev/stg/prod)
- `region`
の組み合わせでリソースを集約します。
この情報から、
- 「prod は削除済みなのに dev/stg が別リージョンに残っている」
- 「SageMaker Studio だけが特定リージョンに取り残されている」
- 「本番が ap-northeast-1 なのに us-west-2 の dev だけが高コスト」
といった**片肺運転状態**を検出します。
---
## ExternalHealthMonitor(外部死活監視)
- 実体
- GitHub Actions: `.github/workflows/external-health-monitor.yml`
- ロジック: `scripts/external_healthcheck.py`
- 設定: `config/healthcheck_targets.txt`
- トリガ
- 毎日 **18:00 日本時間**(cron: `0 9 * * *`)
- 通知
- Slack のみ(失敗時のみ通知)
- 目的
- 「外部から見えるサービス」だけを死活監視し、残リソースは順次削除へ。
---
## ServiceInventory(残リソース洗い出し)
- 実体
- スクリプト: `scripts/service_inventory.py`
- 出力
- `reports/YYYY/YYYY-MM-DD-service-inventory.json`
- `reports/YYYY/YYYY-MM-DD-service-inventory.md`
- 実行オプション(任意)
- `REGIONS=...`(カンマ区切りでリージョン制限)
- `MAX_ITEMS=...`(一覧の最大件数)
- `S3_SKIP_LOCATION=1`(S3のリージョン取得をスキップ)
---
## ZangaiJudge(残骸判定)
- 実体
- ロジックの中心は `scripts/weekly_evaluate.py`
- 集計結果をもとに `status`, `zangai_score`, `flags` を付与
### 主なフラグ例
- `prod_missing_but_dev_exists`
- ある `project` で prod 環境の compute リソースが存在しない一方、
dev/stg 環境が別リージョンに残っている場合。
- `warning_sagemaker_only` / `candidate_sagemaker_only`
- EC2/EKS 等の compute がないのに SageMaker Studio だけが残っている場合。
- `orphan_env`
- prod が存在しない or 完全停止しているのに、
特定の dev/stg 環境だけがリージョンをまたいで存在し続けている場合。
### 人間の役割
- WeeklyCostEvaluator の出力をダッシュボードで確認
- `ZANGAI_CANDIDATE_AUTO` の中から、本当に消してよいものに
- `ZANGAI_CONFIRMED` を付与
- 理由やメモを `reports/YYYY/YYYY-MM-DD-human-notes.md` に追記
- 一方で、残すと決めたものには `KEEP` を付与し、自動判定の対象外にする
---
## SafeDelete(安全な削除フロー)
- 実体
- ローカルダッシュボード(例: `dashboard/app.py`)から
`/actions/delete` のような API を叩き、
`scripts/` 内の削除ロジックを呼び出す。
- 重要なポイント
- **GitHub Actions からは削除・停止操作を絶対に行わない**
- 削除は **ローカル環境からのみ**、明示的な操作で行う。
- 停止候補は `COST-OPS-DEL-CANDIDATE=true` を付与して識別する。
### フロー概要
1. **プリチェック**
- `status == ZANGAI_CONFIRMED` か?
- `BLOCKED_` ステータスが付いていないか?
- リソースが Cognito / Lambda / DB の場合、Repo/IaC 情報が揃っているか?
2. **削除前情報の収集**
- AWS の `Describe*` 結果(設定情報)を JSON で保存
- タグ、Project/Env、リージョン、関連ロググループなど
- 直近30日のコスト(Cost Explorer)を取得し、
- 「削除すると概ねこれくらいのコストダウンになります」を計算
3. **バックアップ/ロールバック素材の作成**
- EC2: AMI作成(EBSスナップショット)
- DB: スナップショットやダンプの作成(→ DBArchiver が担当)
- Lambda: コードzipと設定をダウンロード
- Cognito: UserPool設定をJSONとして保存(ユーザーデータは復元不可であることを明示)
4. **確認ダイアログ**
- 対象リソース、推定コスト削減額、バックアップパス、ロールバック方法を表示
- ユーザーが「理解しました/削除します」にチェックを入れた場合だけ実行
5. **削除の実行**
- boto3 等で terminate/delete
- CloudFormation/CDK 管理リソースについては、
**スタック更新/削除を推奨**し、直接削除は行わない方針も選択可。
6. **ログとステータス更新**
- `logs/YYYY/YYYY-MM-DD-deletion.md` に削除作業を記録
- 次回評価で当該リソースは `deleted=true` として集計・表示
---
## DBArchiver(生きていないデータベースのアーカイブ&削除候補化)
「生きてないデータベースはローカルダウンロードして、消せるものは消す」という方針を具体化するエージェントです。
- 実体
- `scripts/db_archive_and_delete.py`(RDS系を想定、必要に応じてDynamoDB等も扱う)
### 対象
- RDS インスタンス / Aurora クラスター
- (任意)DynamoDB テーブル
- いずれも以下の条件を満たすものを「生きていない候補」とみなす:
- 直近 N 日間、接続数・クエリ数が極端に少ない
- 関連アプリ(Lambda / EC2 / SageMaker)が既に削除されている
- CloudWatch Logs にアプリケーションからのアクセスログがほぼない
### アーカイブポリシー
1. **削除前に必ずアーカイブを取る**
- RDS:
- 最終スナップショットを作成(AWS内バックアップ)
- 可能であれば `mysqldump` / `pg_dump` などでダンプを取得し、
S3 経由 or 直接ローカルにダウンロード
- DynamoDB:
- テーブル内容を S3 / ローカルにエクスポート(サイズにより要検討)
2. **ローカルダウンロード**
- ダンプファイル(例: `db-name-YYYYMMDD.sql.gz`)を
`backups/db/YYYYMMDD/` 以下に保存
- `backups/db/YYYYMMDD/db-name.meta.json` に
- DB識別情報
- 元リージョン
- Project/Env
- 作成時刻
- ロールバック方法(例: RDSリストア手順)
を記録
3. **削除条件**
- `ZANGAI_CONFIRMED` であること
- `BLOCKED_NEEDS_REPO_INFO` でないこと
- DBに依存するアプリケーションのリポジトリ/IaC 情報が確認できていること
- バックアップ(スナップショット or ダンプ)が **成功していること**
4. **削除の実行**
- 条件を満たす場合のみ、
- `delete_db_instance` / `delete_db_cluster` を実行
- 削除実行後の情報も `logs/YYYY/YYYY-MM-DD-deletion.md` に追記する
### Cognito / Lambda との関係
- Cognito / Lambda が「どのDBを使っていたか」不明な場合、
- 当該 DB を `BLOCKED_NEEDS_REPO_INFO` とすることがあります。
- 元リポジトリ(GitHub)や IaC(CDK/CloudFormation)の場所が分からないDBは、
- **原則として削除しない**ポリシーです。
---
## AWS コスト評価ロール(読み取り専用)
GitHub Actions やローカルCLIが安全に評価できるよう、**読み取り専用**のロールを用意します。
### 必要な権限(例)
- `ce:GetCostAndUsage`, `ce:GetDimensionValues`, `ce:GetCostForecast`
- `ec2:DescribeInstances`, `ec2:DescribeTags`
- `logs:DescribeLogGroups`, `logs:FilterLogEvents`, `logs:GetLogEvents`
- `cloudwatch:GetMetricData`, `cloudwatch:ListMetrics`
- `rds:DescribeDBInstances`, `rds:DescribeDBClusters`
- `sagemaker:ListDomains`, `sagemaker:ListUserProfiles`, `sagemaker:ListApps`
- `lambda:ListFunctions`, `lambda:GetFunction`
- `cognito-idp:ListUserPools`, `cognito-idp:DescribeUserPool`
明示的に Deny しておくとよいアクション(保険):
- `ec2:StopInstances`, `ec2:TerminateInstances`
- `rds:DeleteDBInstance`, `rds:DeleteDBCluster`
- `lambda:DeleteFunction`
- `cognito-idp:DeleteUserPool`
- `cloudformation:DeleteStack`
### GitHub Actions からの利用
- IAM ロール例: `GithubCostEvalRole`
- 信頼ポリシー:
- `token.actions.githubusercontent.com`(GitHub OIDC)
- `sub == "repo:ORG/REPO:*"` でリポジトリを絞る
- ロール ARN を `AWS_ROLE_ARN` として GitHub Secret に設定
---
## シークレットと環境変数の設定(CLI 前提)
このリポジトリでは、GitHubのSecretsやローカルの`.env`は **可能な限りCLIから設定**します。
### GitHub Secrets(gh CLI)
```bash
# リポジトリディレクトリで実行
gh secret set AWS_ROLE_ARN --body "arn:aws:iam::123456789012:role/GithubCostEvalRole"
gh secret set AWS_REGION --body "ap-northeast-1"
gh secret set SLACK_WEBHOOK_URL --body "https://hooks.slack.com/services/XXX/YYY/ZZZ"
### ローカル `.env`
`.env.example` をコピーし、必要な値を埋めて使用します。
以上が、現時点でのエージェント設計です。
今後、実装が進むにつれて `AGENTS.md` にもエージェント単位の詳細や実装例を追記していきます。
生み出された Cost-Ops エージェントたち
-
WeeklyCostEvaluator… 週次のコスト・ログ評価(マルチリージョン) -
ZangaiJudge… 残骸判定(スコア+ステータス) -
SafeDelete… バックアップ付き削除フロー -
DBArchiver… 「生きていないデータベース」のローカルダウンロード+削除候補化
この AGENTS.md を使って生まれた損害については全く保証できないしサポートするつもりもないのでどうぞ自己責任で使ってください。でも、消えていくべきリソースを効率よく潰すことに報酬を与えたエージェントは、とても価値があるものでした。
生み出せた AWS-Cost-Opsソリューションたち
- データベースのダンプスクリプト
- SSM Session Manager 経由でプライベートサブネットのRDSに接続
- pg_dump でバックアップ取得後、削除判断
- 運用無人化
- 週次インベントリの自動実行
- Slack通知によるコスト可視化
- Slack通知
通知は意外と大事。コマンドラインで終わってるだけだと、削除担当の知識だけで事故を起こす可能性もある。Slackに通知しておくことで、チーム内での判断とか検索とかも使える。
📊 週次AWSコストレポート
*月額合計: $522.00* (過去30日)
*コスト上位5サービス:*
• EC2 Compute: $172.00
• EC2 - Other: $130.00
• VPC: $22.00
• ECR: $17.00
• Lightsail: $16.00
*リソース状況:*
• EC2稼働中: 3台
• RDS: 0インスタンス, 0クラスタ
その他 生み出せた副産物たち
- 開発プロジェクト開始前のエンジニアさんに向けた技術スタックやドキュメント整備方針(オンボーディングマニュアル)
AGENTS.md に以下を明記:
- 新規リソース作成時は
Project,Env,Ownerタグ必須 - 開発用RDSは
db.t4g.microまたは Serverless v2 を使用 - 1ヶ月使用がなければアラート → 2ヶ月で削除検討
撤退時チェックリスト
退職時/プロジェクト撤退時のマニュアル(オフボーディング)ができたのもとても有意義。
- 関連EC2インスタンスの停止/削除
- RDS スナップショット取得 → 削除
- S3 バケットの整理
- IAM ロール/ポリシーの削除
- CloudWatch ロググループの削除
- Route53 レコードの削除
指差し確認しながらやってくれればいいけど、
仮に上記のドキュメンテーションが不備であったとしても「なんとかなる」という保険的な技術を作れたのは大きい。
service_inventory.py による全リージョン横断スキャン
- タグなしリソースの自動検出と追跡: 削除タグが貼られたら、削除対象だとみんなにわかる。
- 残骸スコア(zangai_score)による削除候補の自動判定
副次的なコスト貢献(利益)
- 発見した累計無駄 : 約75万円 今後の年間削減 : 約51万円 現時点での合計貢献額 : 約126万円 (1 USD = 155 JPY で計算)
会社で、年間126万円の利益をAIだけで出そうと思ったらどうすればいい?それは「片付けをすればいい」です。Claude Maxのサブスクリプション費用を捻出してあげるためにも!
キーになるプロンプト(基本編)
「バイブコーディングの基本」みたいなものは存在しないので、めっちゃ重要なプロンプトをいくつか紹介しておきますね。初回なので。
なおGitHubの操作もおぼつかないような方々はこちらの動画もどうぞ。
最初の一言
これめっちゃ大事。
これは何?日本語で応答して
調査開始
はい、現状、コストが発生してます。2026/1/1の動作状況を把握しましょう。
肯定しつつ、次にやることを時間軸を指定して問うている。
判断と実行
ダンプして教えてください
DBを書き出して、解説させる。これをコマンドライン1行で書くのは難しい。
削除で問題ありません。このDBが作られてから今までの無駄にしてきたコストを累計してみてください。
運用自動化
いいレポートが作れたときに大事な1行。
↑このレポートを毎週月曜日にGitHub Actions経由でSlack通知できますか?
もしこの1年先もこれをやっていなかったとしたら
追加で 約51万円 が無駄になっていました。しかも、リソースは増える一方。気づいたときには手遅れ…なんてことも。ゾッとします。
まとめ
AIやバイブコーディングでお金を稼ごうと思ったら、まずは「片付けろ」!!
新しいものを作る前に、古いものを片付ける。これが第1回の教訓です。ものづくりの現場でも「5S」が大事ですからね!整理・整頓・清掃・清潔・しつけの5つの要素です。
Claude Code(Opus 4.5)との対話だけ生まれた価値
- 17ヶ月放置された空のデータベースを発見・削除
- 30ヶ月放置されたWorkSpaces用Directory Serviceを発見・削除
- 週次コスト監視の自動化を実装
- チーム向けドキュメントをほぼ自動整備
- この原稿
- AGENTS.md
所要時間: 約2時間(期間としては1ヶ月以下)
削減効果: 最低でも年間 約51万円
ROI: ∞(コード書いてないから開発コスト0円)
以上です!多分続きます。
AICU AIDX Labは、AI時代に「つくる人をつくる」をビジョンに
企業が今すぐ価値に貢献できるAIソリューション技術を開発しています。

