メインコンテンツまでスキップ

課金構造の地図と安全な終わり方: コストの全体像と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 の機能開発や、運用の中で見えてくる課題に応じて、必要な箇所を深掘りしていくことになります。

次に読む​

Footnotes​

  1. 出典: Stopping an Amazon RDS DB instance temporarily。停止は最大 7 日間で、7 日を超えると自動的に再起動するとしています。 ↩

  2. 出典: 同上。停止中もプロビジョニングストレージとバックアップストレージの課金は継続するとしています。 ↩

  3. 出典: StopDBInstance API Reference。RDS Custom・Aurora MySQL・Aurora PostgreSQL には適用されないとしています。 ↩

  4. 出典: 第4章4.5 節、およびIntroducing Amazon VPC Regional NAT Gateway。単一の NAT Gateway が複数のアベイラビリティゾーンを自動的にカバーする一方、アベイラビリティゾーンごとに帯域を確保する動作をしており、実際の課金が AZ ごとに 2 個用意する構成より安くなるかは第 4 章時点で確認できておらず、今回の fact-check でも解消していません。 ↩ ↩2

  5. 出典: terraform MCP (hashicorp/aws provider v6.53.0、aws_nat_gateway)。availability_mode = "regional"を指定しavailability_zone_addressを省略すると、ENI 検出時に自動的に AZ・EIP を拡張する auto mode になるとしています。 ↩

  6. 出典: AWS NAT Gateway now supports regional availability (2025 年 11 月の AWS 公式アナウンス)。AWS GovCloud (US) リージョンと中国リージョンを除く全ての商用 AWS リージョンで利用可能だとしています。 ↩

  7. 出典: DeleteHostedZone API Reference。ホストゾーンはデフォルトの SOA・NS レコードのみを含む状態でないと削除できず、それ以外のレコードは事前に削除が必要だとしています。 ↩