はじめに
この記事は Fusic Advent Calendar 2025 10日目の記事です。
この記事を読んでくださっている皆さん、こんにちは。 Fusic でエンジニアをしている政谷です。
今日は、「検証環境ならではの方法で AWS 利用料を削減した話」について書きます。
コスト削減の背景
システム開発が一定の規模や影響度になると、次のような理由から検証環境、いわゆるステージング環境が必要不可欠になってきます。
- 開発中の機能についてお客様と認識を合わせる
- 本番相当のスペックやデータ量に準じて負荷試験を実施する
一方で、検証環境はビジネス上非常に重要な意味を持つにもかかわらず、数字の上では「コスト」として計上される存在です。そのため、
- できるだけ運用コストを下げたい
という性質も持っています。
弊社のある案件でも、案件規模が大きくなるにつれて、当初はビジネス規模に対して無視できていた検証環境のコストが徐々に問題となり、追加のコスト削減施策が必要になりました。
システムおよびコスト削減の前提
今回コスト削減の対象となったシステムは、下記の特性を持っています。
- システムは AWS 上に構築されており、検証環境も本番相当の構成で構築されている
- システムの提供形態上、いわゆる「サイロモデル」となっている
- システムの提供先が増えるごとに同一構成のシステムが増えていく
- 各サイロが微妙に個別カスタマイズされた上で独立して稼働しているため、検証環境も各サイロごとに用意されている
- RI や CSP と言った、パっと思い付く AWS コスト削減の施策は実施済み
主なコストポイント
まずは、上記の前提のもとで、検証環境の目的を損なわない範囲で削減可能なコストポイントを洗い出しました。
1. IPv4 グローバル IP アドレス
AWS の料金体系の改訂により、2024 年 2 月 1 日以降、すべてのパブリック IPv4 アドレスに対して時間課金が発生するようになりました。
構成上、Fargate タスクがコンテナイメージを ECR から pull する際にパブリック IP アドレスを利用する必要がありました。また、サイロの数が 100 を超える規模で存在していたため、検証環境で利用しているグローバル IP アドレスのコストが無視できないレベルになっていました。
2. アプリケーションサーバー(Fargate)
サイロの数が増えるごとにアプリケーションサーバーの数も増加するため、Fargate の利用料が大きなコストポイントとなっていました。
しかし、各システムが独立して稼働しているため、アプリケーションサーバーを統合することはできず、単純に稼働する Fargate タスク数を削減することはできない状況にありました。
3. ALB
Fargate 同様に、サイロの数が増えるごとに ALB の数も増加するため、ALB の利用料も大きなコストポイントとなっていました。
こちらも各サイロが独立して稼働しているため、ALB を単純に削減することはできませんでした。
4. バッチ処理
システム運用に関わるバッチ処理も Fargate タスクとして稼働するように実装していました。
システム構築当初はバッチ処理が数件しかなかったため、EventBridge により定期的にタスクを起動し、
- バッチ処理対象のデータがあれば処理を実行
- データがなければそのままタスクを終了
という形で実装していました。
しかし、システム運用が進むにつれてバッチ処理の数が増加し、バッチ処理用の Fargate タスクの使用料(および IPv4 課金)も無視できないレベルとなってしまいました。
コスト削減施策
上記のコストポイントを踏まえて、コスト削減施策として、以下の施策を実施しました。
1. パブリック IPv4 アドレスの削減
ECR からイメージを pull する際にパブリック IP アドレスを利用する必要があったため、当初は以下のような案を検討しました。
- NAT Gateway を導入する
- ECR の VPC エンドポイントを導入する
これらを導入すれば、Fargate 自体にパブリック IP が不要となるよう構成変更できますが、NAT Gateway や VPC エンドポイントは通信量に応じた課金が発生するため、コンテナイメージという比較的大きな通信を行う今回の構成とは相性が悪いと考え、導入を見送りました。
次に
- IPv4 ではなく IPv6 に切り替える
という案を考えましたが、、コスト削減施策実施期間の当時は ECR のエンドポイントが IPv6 に対応しておらず、IPv6 経由での通信も利用できませんでした。
そこで最終的に、
- Fargate 自体はプライベートサブネットに配置
- ネットワーク性能の高い EC2 インスタンスを NAT インスタンスとして配置
- その NAT インスタンスに Elastic IP アドレスを割り当て
- ECR への通信は NAT インスタンス経由で実施
という構成に変更しました。
これにより、
- サイロ分のパブリック IPv4 アドレスの利用料 360 * 100サイロ)
を
- NAT インスタンスの台数分 IPv4 アドレスの利用料 7.2$ 程度(2 AZ 配置)
- NAT インスタンス自体のコスト約120$程度(c7gn.medium * 2 AZ 配置)
と、半分以下のコストに押さえられ、今後サイロが追加されてもパブリック IPv4 アドレス課金が発生しない構成に変更できました。
2. アプリケーションサーバーの停止
検証環境は、基本的に業務時間内のみ利用されることが多いため、業務時間外はアプリケーションサーバーを停止するように構成を変更しました。
具体的には、EventBridge のスケジュール機能を使い、以下のような制御を行っています。
- 業務終了時刻に、各 ECS サービスのオートスケール設定を 0 に変更する API を実行
- 業務開始時刻に、元のスケール設定に戻す API を実行
これにより、検証環境の Fargate 利用時間をほぼ半分に削減でき、Fargate の利用料もおおよそ半額程度まで削減することができました。
3. ALB の集約
サイロごとに ALB を用意していましたが、ALB は 1 台で複数のドメインやパスを処理することが可能です。
そのため、ALB を集約し、ALB の台数自体を削減しました。
具体的には、
- ALB のリスナールールでホストヘッダによるルーティングを設定し、各サイロのドメインに応じて適切なターゲットグループへルーティングするように設定
- 各ドメインの ACM 証明書を ALB に適用
- R53 の各ドメインの向き先を、集約した ALB に向ける
これにより、検証環境における ALB の利用料を約 1/25 まで削減することができました。
また、この記事を書くにあたり、Application Load Balancer あたりの証明書 の制限について調べたところ、引き上げが可能だったので、さらに削減できそうです。
4. バッチ処理のイベント駆動化
バッチ処理用の Fargate タスクは EventBridge による定期実行で起動していましたが、これを AWS Batch を利用したイベント駆動型の構成に変更しました。
具体的には、
- 管理画面上から、バッチ処理が必要な操作が行われたタイミングで AWS Batch にジョブを投入
- ジョブが投入されたタイミングで Fargate タスクが起動し、必要なバッチ処理を実行
という流れに変更しています。
これにより、「データがないがとりあえず起動するだけ」のタスク実行がなくなり、バッチ処理用の Fargate タスクの利用料を大幅に削減することができました。
まとめ
以上の施策により、検証環境の AWS 利用料を大幅に削減することができました。
検証環境だからこそ実現できる施策もありますが、AWS コストに悩んでいる方の参考になれば幸いです。
Kensuke Masatani / 政谷 賢祐 / まさたに けんすけ / マサタニ ケンスケ
新しいプロフィールへようこそ!