課金構造の地図と安全な終わり方: コストの全体像とdestroy手順
前章で、Tasuku のインフラはmodules/ + envs/dev,prodという複数環境を扱える構成に育ちました。この最終章では、視点を変えて 2 つのことをします。1 つは、各章に散らばっていたコストの話を 1 枚の地図に集約すること。もう 1 つは、この連載を通じて作ってきた学習用インフラを、安全に終わらせる手順を示すことです。最後に、この連載がスコープ外に置いた事項を、次の一歩として整理します。
12.1. 課金構造の地図
この連載は、第1章以来「料金の絶対額は書かず、課金ディメンションと相対比較のみを示し、詳細は公式料金ページを参照する」という方針を貫いてきました。個々のリソースのコストへの注意は各章の:::warningで触れていますが、全体を俯瞰する地図はまだ書いていません。ここで 1 枚にまとめます。
| リソース | 課金ディメンション | 既出章 |
|---|---|---|
| NAT Gateway | 稼働時間 + 処理データ量 | 第4章 |
| Application Load Balancer | 稼働時間 + LCU (リクエスト量等に応じた単位) | 第6章 |
| Route 53ホストゾーン | 月額固定 | 第7章 |
| ACM証明書 | なし (ALB等への統合利用は無料) | 第7章 |
| ECS Fargate (web/api) | vCPU・メモリの稼働時間、Auto Scalingでタスク数に応じて変動 | 第8章・第10章 |
| RDS (Multi-AZ) | インスタンス稼働時間 (Multi-AZは2台分) + ストレージ | 第9章 |
| S3 (3バケット) | ストレージ量 + バージョニングによる旧バージョン保持分 | 第5章 |
| S3 Gatewayエンドポイント | なし (VPCエンドポイントとしては無料) | 第5章 |
| ECRリポジトリ | 保存イメージのストレージ量 | 第8章 |
| CloudWatch Logs | ログの取り込み量 + 保持期間分のストレージ | 第8章 |
| Secrets Manager | シークレット数 + API呼び出し回数 | 第9章・第10章 |
Fargate・ECR・CloudWatch Logs・Secrets Manager は、個々の章では設定の説明が中心で、明示的なコスト注意はしていませんでした。ここで初めて課金ディメンションとして言及します。ACM 証明書と S3 Gateway エンドポイントは、対比のために「無料」の行として並べています。無料であることが常に自明とは限らないため、他の有料リソースと並べて確認できるようにする狙いです。
12.2. 削減定石
第11章11.5 節の env 差分は、そのまま dev 環境のコスト削減にもなっています。RDS のmulti_az = falseはインスタンス 1 台分の課金で済み、Auto Scaling のmin_capacity = 1は常時稼働するタスクを最小限にします。ここでは、それに加えられる削減定石をいくつか示します。
RDSの一時停止です。使わない期間は RDS インスタンスを止められます。停止は最大 7 日間有効で、7 日を過ぎると自動的に再起動します。1 ただし、停止中も止まらない課金がある点に注意してください。プロビジョニングしたストレージ (Provisioned IOPS を含む) と、バックアップストレージの課金は、停止中も継続します。2 完全に無課金になるのはインスタンスの稼働時間分だけです。この機能は Aurora MySQL・Aurora PostgreSQL・RDS Custom には適用されません。3 Tasuku は通常の PostgreSQL (Aurora でない) のため、この制約には該当せず利用できます。
aws rds stop-db-instance --db-instance-identifier tasuku-dev-db
NAT Gatewayの構成見直しは、削減定石として挙げきれません。第4章4.5 節では、単一の NAT Gateway で複数のアベイラビリティゾーンをカバーする「Regional NAT Gateway」というモードに触れました。そこでは「コードの見た目が 1 個になることと、実際の課金が AZ ごとに 2 個用意する構成より安くなることは別の話で、後者は確認できていない」と留保していました。4 このモードが実在しavailability_mode = "regional"を指定するだけで使え、5 ap-northeast-1 でも利用可能であること6は、今回の fact-check で確認できました。しかし、第 4 章が留保した核心の疑問、すなわち「実際に課金が AZ ごとに 2 個用意する構成より安くなるか」は、依然として確認できていません。Regional NAT Gateway も実際にはアベイラビリティゾーンごとに帯域を確保する動作をしており、4 見た目の個数がコストに単純に比例するとは限らないためです。この選択肢はここでも採用を推奨せず、コード変更も行いません。
Auto Scalingの最小値は、すでに第11章の env 差分で dev=1 に設定済みです。負荷テストなど一時的に高い性能が必要な場面以外は、この値を上げる理由はありません。
これらはすべて、絶対額でなく「何を減らせば何が減るか」という構造の話です。実際の削減額は、公式の料金ページとご自身の利用量に照らして確認してください。
12.3. 安全なdestroy
この節が対象にするのは、第11章で作ったenvs/dev・envs/prodです (旧main/の後始末は前章 11.8 節で扱い済みです)。素朴にterraform destroyを実行すると、いくつかのリソースが削除を拒否します。壊す前に確認すべきことを棚卸しします。
| リソース | 保護設定 | destroy前に必要な作業 |
|---|---|---|
| RDSインスタンス | deletion_protection (prod環境はtrue) | deletion_protection = falseに変更して再applyしてから destroy する |
| S3バケット (添付・ALBログ) | force_destroy未設定 | バケットを空にするか、一時的にforce_destroy = trueを設定して再apply |
| ECRリポジトリ | force_delete未設定 | イメージを削除するか、一時的にforce_delete = trueを設定して再apply |
| Route 53ホストゾーン | デフォルトのSOA・NSレコード以外は削除必須 | apex・apiのAliasレコード、ACM検証用レコードを削除する (ホストゾーン自体を削除すればSOA・NSは自動的に削除される) 7 |
| ACM証明書 | リスナーからの参照 | 443番リスナーの依存はTerraformの依存グラフが自動的に解決する (追加作業は不要) |
bootstrap/が作る tfstate バケットは、最後にdestroyします。先に消してしまうと、envs/dev・envs/prodの backend が参照する state の置き場自体が失われます。第5章5.3 節の「バケットがないと backend を設定できない、backend がないとバケットを作る state を置けない」という鶏と卵の関係が、destroy 時には逆向きに現れる形です。このバケットも上表の添付・ALB ログバケットと同様にforce_destroyを設定していないため、destroy 前にバケットを空にするか、一時的にforce_destroy = trueを設定して再 apply する必要があります。
前章11.6 節で触れたmovedブロックとの関係も整理しておきます。movedは既存のリソースを壊さずに新しいアドレスへ付け替えるための工夫でした。destroy は逆に、意図してリソースを壊す操作です。目的は正反対ですが、どちらも「今あるリソースの状態を正確に把握したうえで、Terraform の操作を組み立てる」という点は共通しています。
12.4. 次の一歩
この連載でスコープ外に置いた事項のうち、続けて手を付けやすいものを挙げます。
第9章9.4 節で、Fargate は第10章の Auto Scaling でタスクの数こそ動的に調整するものの cpu/memory の値自体は見直されず、RDS のインスタンスクラス (db.t4g.micro) も同様に見直す章がこの連載になかったことに触れました。この問いへの答えは、「インスタンスサイジングの見直しは運用フェーズの課題」というものです。CloudWatch のメトリクス (CPU 使用率、空きメモリ、接続数など) を監視し、実際の負荷傾向が見えてから見直すのが実務的な順序です。構築時点で先回りしてサイズを変える理由は、まだありません。
他にも、次のような発展先があります。
- CI/CDパイプライン化: 第11章11.2 節のデプロイ標準手順を、GitHub Actions 等で自動化する
- CloudFront: 第1章でスコープ外とした、ALB の手前に CDN を置く構成
- マルチリージョン・DR: 単一リージョン構成から、災害復旧を見据えた複数リージョン展開へ
- IAM permissions boundary: 第3章3.6 節で仕組みだけ説明して導入を見送った、Terraform 実行者の自己権限昇格リスクへの構造的対策
本章のまとめ
- 各章に散在していたコストの話を、リソース×課金ディメンションの 1 枚の表にまとめました。Fargate・ECR・CloudWatch Logs・Secrets Manager は、この章で初めて課金ディメンションとして言及しました
- 削減定石として、RDS の一時停止 (ストレージ課金は継続する点に注意) と Auto Scaling 最小値の 2 つを示しました。Regional NAT Gateway は選択肢として存在は確認できましたが、第 4 章が留保したコスト削減効果は今回も解消できず、採用は見送りました
envs/dev・envs/prodを安全に destroy する手順を、RDS・S3・ECR・Route 53 のリソース別に整理しました。tfstate バケットは最後に destroy します- 第 9 章で留保した RDS インスタンスサイジングの非対称性を、運用フェーズでの見直し事項として回収しました
- CI/CD・CloudFront・マルチリージョン・permissions boundary を、この連載のスコープ外に置いた次の一歩として挙げました
この連載は、VPC から RDS・ECS サービスまでの構築、環境分離、そして安全な終わらせ方までを扱いました。ここから先は、実際の Tasuku の機能開発や、運用の中で見えてくる課題に応じて、必要な箇所を深掘りしていくことになります。
次に読む
- 第 11 章: デプロイの標準化と環境分離: E2E 疎通確認、ECS デプロイ標準手順、module + envs 構成へのリファクタ
- 連載の目次: 全 12 章の構成と読み進め方