Terraformで作って壊すたびに電話番号の枠が減る — Amazon Connectの180日ルールでプロジェクトを畳んだ話

Terraformで作って壊すたびに電話番号の枠が減る — Amazon Connectの180日ルールでプロジェクトを畳んだ話 AWS

コールセンターをフルIaCで建てて通話の感情をリアルタイム分析する crossbar_telepath の最終回である。プロジェクトをアーカイブした。

技術は完走した。死因は技術ではなく、電話番号だった。この記事はその死因の解剖記録である。同じ轍を踏む人を減らすために書く。

発端: 番号を1本も持っていないのに「枠超過」

8月頭、実呼テストのためにdestroy済みのConnect基盤を terraform apply で建て直した。インスタンス・コールフロー・Lambda・SQSまでは何事もなく生えた。電話番号だけが生えなかった。

resource "aws_connect_phone_number" "main" {
  target_arn   = aws_connect_instance.this.arn
  country_code = var.phone_number_country_code
  type         = var.phone_number_type
  description  = "crossbar-telepath inbound verification number"
}

このリソースが FAILED 状態で作られる。CLIで直接取りにいっても同じで、search-available-phone-numbers は候補を返すのに、claim-phone-number が枠超過で落ちる。

ここで頭が混乱する。このアカウントが保有している電話番号は0本である。 クォータ(Phone numbers per instance、既定5)のどこを消費しているのか。

謎解き: 解放した番号は180日間「居座る」

答えはドキュメントの一文にあった。releaseした電話番号は、解放後180日間、クォータにカウントされ続ける。

つまりこうだ。このプロジェクトは開発の流儀どおり、検証のたびに apply → 架電E2E → destroy を繰り返してきた。7月に2回、8月に1回。番号はそのたびに取得され、解放された。手元には何も残っていないが、枠の上では3本ぶんの幽霊が180日間居座っている。

さらに追い打ちがある。取得に失敗した試行もまた枠を食うのだ。「枠が空いてないだけかもしれない」とリトライを重ねると、失敗のたびに状況が悪化する。私はこれで残りの枠も溶かした。

AWSの立場で考えれば、このルールは正しい。番号を取っては捨てを高速に繰り返せるなら、迷惑電話業者は着信拒否リストを永遠にすり抜けられる。180日ルールは番号ローテーション悪用への対策であり、電話網の側の防衛としては真っ当である。

ただしこれは、IaCの「作って壊す」様式と根本的に相性が悪い。 サーバーは壊して建て直せば同じものが手に入るが、電話番号は壊した瞬間に180日分の枠を持ち逃げする。

対策1: 番号の常設化 — 正しかったが、遅かった

気づいた時点で方針を転換した。番号は使い捨ての設定値ではなく資産である。維持コストを実測すると:

  • 電話番号: $0.06/日 ≒ $1.8/月
  • KVS暗号化のKMSキー: $1/月
  • Connectインスタンス自体・待機中のKVS/Lambda/SQS: ほぼゼロ

月$3弱で「取得ガチャ」と180日ルールから解放される。 destroyの対象から番号を外し、Connect基盤ごと常設にする——これが正解だった。

問題は、正解に気づいたのが枠を使い切った後だったことだ。常設にしようにも、その最初の1本が取れない。 幽霊が消えるのは2027年1月末。5か月先である。

対策2: クォータ引き上げ申請 — 個人開発とKYCの壁

残る道はクォータ引き上げ(L-8F812903、5→15)だった。Service Quotasから申請すると、サポートケースに変換される。

aws service-quotas list-requested-service-quota-change-history-by-quota \
  --region ap-northeast-1 --service-code connect --quota-code L-8F812903 \
  --query 'RequestedQuotas[0].{Status:Status,Desired:DesiredValue}'
{ "Status": "CASE_OPENED", "Desired": 15.0 }

やりとりは3往復あった。

  1. インスタンスARNの照会 → 提供
  2. 「内部チームに回した。最長5営業日待て」
  3. そして最後に来たのがこれである:

A valid business document with the business number partially redacted (showing only the last four digits). Please ensure the business name and all four corners of the document are clearly visible.

A brief description of your business and what it does.

The business use case for this limit increase request.

事業証明書類の提出要求だ。電話番号の取得に事業者確認(KYC)が要るのは知っていたが、クォータの引き上げ審査にも同じ土俵が適用される。番号という資源に触る以上、そこに個人と事業者の区別ができる抜け道は用意されていない、ということだろう。

個人事業主の開業届で応じる道はあった。書類も用意した。だが冷静に考えた。これは趣味の技術検証プロジェクトである。検証用の番号1本のために事業書類を審査に載せ、以後もPSTNの制度側と付き合い続ける——そのコストは、このプロジェクトが検証したかったこと(それはもう検証し終わっている)に対して重すぎる。

ここで店じまいを決めた。

埋葬式: destroyとシークレット監査

畳むと決めたら手際よくやる。消したら困るからと分けて建てたCognito(認証基盤)は、deletion_protection = "ACTIVE" で自らのdestroyを拒否するように作ってあった。これを外すところから埋葬が始まるのは、少し皮肉だった。

resource "aws_cognito_user_pool" "this" {
  name                = "crossbar-telepath"
  deletion_protection = "INACTIVE" # プロジェクト終了(2026-08-24): 埋葬のため保護を解除
  # ...
}
=== [2/3] auth: destroy ===
Destroy complete! Resources: 10 destroyed.
=== [3/3] infra: destroy ===
Destroy complete! Resources: 11 destroyed.

Connectインスタンス0件・Cognitoプール消滅・KMSエイリアス0件をAPIで確認し、課金は完全にゼロになった。番号を持っていないことが、畳むときだけは楽だった。

リポジトリは公開に切り替えるため、全69コミットの履歴を監査した。APIキー・秘密鍵・JWT・個人情報(電話番号・住所)のパターンを全リビジョンに対して走査する。

git grep -I -l -E \
  'AKIA[0-9A-Z]{16}|sk-[A-Za-z0-9_-]{20}|BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY|eyJhbGciOi' \
  $(git rev-list --all)

ヒットなし。.env.example は歴代12バージョンすべてで OPENAI_API_KEY= が空であることも確認した。

到達点 — 技術は完走している

供養として、このプロジェクトが持ち帰ったものを並べておく。どれも電話番号がなくても再現できる(そのための合成通話フィクスチャまで作った)。

最終形はReact+TypeScript+ViteのSPAにCognito認証(SRP)とロール別認可(監視卓/応対者)まで載り、バックエンド53本+フロント22本のテストとCIが守っている。動くものは録音リプレイで今日でも動く。

学び

  1. 電話番号はサーバーではない。資産である。 IaCの「作って壊す」に番号を巻き込んではならない。最初の1本を取ったら lifecycle { prevent_destroy = true } を張り、destroyの対象から外す。月$2の維持費は、180日の呪いと引き換えなら安い
  2. 失敗した操作が枠を消費する設計がある。 「もう一回試せばいいか」が通用しない資源では、リトライは無料ではない。連打する前にドキュメントの課金・クォータの節を読む
  3. PSTNは事業者の世界である。 番号に触る個人開発は、技術ではなくKYCが律速になることを予算に入れておく。これは規制の失敗ではなく、迷惑電話対策として合理的な制度がそこにあるだけだ
  4. 元・電話網エンジニアとして言えば、これは既視感のある話だった。電話番号が「加入権」という資産で、施設設置負担金を払って手に入れるものだった時代がある。クラウドのAPIの向こうでも、番号は今なお資産として制度設計されている。APIで一瞬で取れることと、使い捨てにしてよいことは違う

転生の可能性

心理分析のコア——話者別ストリーム→文字起こし→テキスト+声のトーンの融合判定→リアルタイムUI——はPSTNに依存していない。マイク入力や会議音声に載せ替えれば、電話番号なしで生き返る。埋葬とは、そういう可能性ごと土に還すことではなく、掘り起こせる場所に記録を残すことである。

リポジトリ: crossbar_telepath(埋葬にあわせて公開)

コメント

タイトルとURLをコピーしました