AWSのコストを削減する

# はじめに

弊社はAmazon Web Services (AWS) を積極的に活用している会社で、先輩曰く「自称日本で最も複雑にAWSを用いている会社」のようです。その真偽はさておき、確かにAWSのリソースを様々に活用しております。そのため、AWSのコストも大きく、事業が大きくなるにつれコストも大きくなってまいりました。私は開発部所属なのですが、コスト削減担当者となり、開発の観点からコスト調査とその対策を考えてまいりました。その取り組みをご紹介します。もし他にアイデアをご存じの方は重複を恐れずにお気軽に教えていただけますと幸いです。

※本記事は網屋 Tech Blog Advent Calendar 2024の 12 月 14 日分の記事です。

# コスト調査は面白い
私は開発部に所属してコードを書くことがメインの仕事なのですが、コスト調査も面白いと感じています。その理由は、コストもソフトウェアの側面の一つであるからだと思います。一見正常に動いているソフトウェアであっても何らかの異常が裏で存在している場合があります。その裏側を覗く手段の一つがコスト調査であると思います。開発者として「よいソフトウェアを作りたい」と常々考えておりますが、「よい」の観点が増えるのが面白さだと思います。

# 削減結果
いきなりですが、弊社のAWSのコストの削減結果です。
![for_qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957558/647b1645-12fd-9bb1-f26f-75587fa0b892.png)


8月までは事業が拡大していくにつれてコストが増大しておりました。8月末ごろから本格的にコスト削減に取り組んだ結果、未だ事業が拡大しているにもかかわらずコストを大幅に削減することに成功しました。

# コスト削減のアイデア集

## 目次

- 0: 以下のアイデアを目的化しない
- 1: まずはともあれ可視化する
    - 1-1: tagをつけ、Cost Explorerの使い方を習熟する
    - 1-2: CloudTrailで証跡をとり、調査。そのためのコードを書く or Athenaで調査する
    - 1-3: S3 Storage Lensで調査しやすいようなアーキテクチャにする
    - 1-4: CloudWatch Logs Insightsを活用する
- 2: 不要なアカウント、リソース、設定の削除する
    - 2-1: リソースはCost ExplorerやS3 Storage Lensなどで調べる
- 3: 変動が大きいものと小さいものに分けて監視する
    - 3-1: 変動が大きいリソースは変動の傾向をつかみ、正常な変動かどうかを判断する
    - 3-2: 変動が小さいリソースは不要な定期実行とスパイクを発見しやすい
    - 3-3: 相関があるはずのリソースを比較する
- 4: アーキテクチャを見直す
    - 4-1: 不要なリトライをさせない
    - 4-2: イベントがない場合駆動させない(イベント駆動とは別)
    - 4-3: スケールに合わせてECSのTask定義などを使い分ける
- 5: AWSの特性を理解する
    - 5-1: Lambdaのウォームスタート
    - 5-2: ECSの実行にVPCの料金もかかる
- 6: AWSのサービスをうまく活用する
    - 6-1: S3ならばIntelligent-Tiering, Glacierなど
    - 6-2: アーキテクチャのARM化
    - 6-3: LambdaとECSを比較して用いる
- 7: AWS外のサービスをうまく活用する
    - 7-1: 外部のAPIから取得するデータ量を必要十分にする

## 本文
### 0: 以下のアイデアを目的化しない
大事なことなのですが、以下の表題はコスト削減のアイデア集ですが、必ずしもすべてのシチュエーションにマッチするとは限りません。コストが削減されるのが目標であるので、コスト削減につながるのかを検討して、手段を目的化しないのは重要だと思います。

---

### 1: まずはともあれ可視化する
コスト調査にあたって、まず調査ができるようにします。

#### 1-1: tagをつけ、Cost Explorerの使い方を習熟する
まずは異常が起こっているリソースを特定するために、リソースにタグをつけ、Cost Explorerで監視できるようにしました。また、Cost Explorerのフィルターで絞り込みグループ化でランキングすることで細かいリソースの料金の変動を確認することができます。

#### 1-2: CloudTrailで証跡をとって調査するためのコードを書く or Athenaで調査する

異常が起きているリソースの精密な調査を行うには、どのアカウントのどのリソースがアクセスしたのかを特定する必要があり、そのようなデータを収集するためにCloudTrailというサービスを利用しています。CloudTrailで取得できるサービスのログを集計して調査するプログラムも作成しております。Athenaを用いて調査をすることもできるようです。CloudTrailの料金もありますので、必要に応じて1時間や1日に絞って詳しい証跡を取るなどの工夫をします。

#### 1-3: S3 Storage Lensで調査しやすいようなアーキテクチャにする

S3 Storage Lensは無料でS3のコストを調査できます。ただ、無料で調査できるメトリクス情報には制限がありますので、その制限内で調査ができるようなアーキテクチャにしておくと無料で調査が可能です。たとえば、おもに調査したいデータがわかっている場合はそのデータを保存する専用のバケットを設けておくなどです。

#### 1-4: CloudWatch Logs Insightsを活用する

CloudWatch Logs Insights はCloudWatchのログをさらに詳しく統計情報などを得たい場合に有用です。

---

### 2: 不要なアカウント、リソース、設定の削除する
問題点を発見したらコードやアーキテクチャの修正を行うわけですが、それらの修正を行う前に、地道なコスト削減の、不要なアカウントとリソースと設定の削除を行うとよいと思われます。理由は、どのリソースに変更を加えるとコストがどう変動するのかの知見を得るためです。ひとつのリソースの削除で付随して下がるコストなどを発見できる場合があります。
#### 2-1: リソースはCost ExplorerやS3 Storage Lensなどで調べる
不要であるリソースの発見はCost ExplorerやS3 Storage Lensが役に立ちます。

---

### 3: 変動が大きいものと小さいものに分けて監視する
コストが妥当であるのかを判断する際、変動費と固定費に分けて調べるのが役に立ちます。

#### 3-1: 変動が大きいリソースは変動の傾向をつかみ、正常な変動かどうかを判断する。
コストの変動が大きいリソースは、まず変動していてよいリソースなのかを考えました。変動すべきでない定期実行されているリソースであるのに変動しているものの正常化をはかります。また、変動自体も週などの単位でみると傾向がつかめるケースもあります。

#### 3-2: 変動が小さいリソースは不要な定期実行とスパイクを発見しやすい。
変動が小さいリソースは定期的にスケジュールされているものですので、コストが妥当かを調べます。また、変動が小さいリソースのコストがスパイクしたことに気付くのは容易です。

#### 3-3: 相関があるはずのリソースを比較する
代表的な相関としてはリソースとそのリソースに付随するcloud watchの相関を調べました。このようにリソースが相関する場合がありますので相関していないのを観測すると異常に気付くことができます。 5-1: Lambdaのウォームスタート、5-2: ECSの実行にVPCの料金が付いてくる で紹介しますが、相関を調べているとAWSの仕様に気付く場合があります。

---

### 4: アーキテクチャを見直す
ここからが開発の仕事と関わります。コストを含め、異常の発生しにくいアーキテクチャを開発します。

#### 4-1: 不要なリトライをさせない
ECSやLambdaをStep Functionsで用いていると、エラーが起きた際にリトライさせたいケースがあります。その際はリトライで改善される可能性がある場合のみリトライさせるようにするとコスト削減につながります。ECSの実行をStep Functionsの出力で次のstateに引き渡す方法が意外と検索しても見つからなかったので苦戦しましたが、TaskTokenというのを用いて実現させることができました。

#### 4-2: イベントがない場合駆動させない(イベント駆動とは別)
定期実行されているコードは無駄にコストがかかっている場合があります。イベントがある場合のみで十分の場合、イベントがない場合には定期実行させないような工夫をします。また、これはイベント駆動とは異なることに注意します。定期実行を上回るイベントが発生している場合イベント駆動にするとむしろコストが上がる場合があります。その場合、すこしイベント結果をプールさせてから実行するなどの工夫をします。

#### 4-3: スケールに合わせてECSのTask定義などを使い分ける
ECSやLambdaの実行の際のメモリやCPU性能などは一括設定にするのではなく、スケールにあわせて柔軟に対応できるようなアーキテクチャにしておきます。

---

### 5: AWSの特性を理解する
AWSの仕様を理解していないと謎のコストスパイクを起こす可能性があります。

#### 5-1: Lambdaのウォームスタート
Lambdaにはウォームスタート、コールドスタートというものが存在します。連続でLambdaを呼び出した際に前のLambdaのリソースをAWSが使いまわす場合があります。その際にloggerの扱いが適切でないとLambdaのcloud watchのコストが爆増するケースがありました。また、Lambdaの実行されているローカルに一時ファイルを保存する場合なども思わぬバグが生まれる場合があるため注意が必要です。

#### 5-2: ECSの実行にVPCの料金もかかる
ECSのTaskDefinitionにタグを付けた際に気付いたことですが、ECSの実行にVPCの料金もかかる場合があります。VPCの料金をTaskDefinitionのtagでグループ化することができます。

---

### 6: AWSのサービスをうまく活用する

AWSが公式で用意しているサービスを用いてコスト削減する手段を模索します。

#### 6-1: S3ならばIntelligent-Tiering, Glacierなど
S3には通常のstorage classだけでなく、Intelligent-Tiering, Glacierなどのクラスが存在します。オブジェクトごとに使い分けることができるため非常に柔軟に用いることができます。バックアップのために保存するが使わないデータなど、ユースケースに応じてコスト計算を行い、Intelligent-Tiering, Glacierを積極的に活用します。

#### 6-2: アーキテクチャのARM化
ECSの実行環境をx86からARMに変えるとコストを削減できます。

#### 6-3: LambdaとECSを比較して用いる
LambdaとECSは状況に応じてコスト面での有利不利が存在します。ユースケースにあわせてLambdaとECSを使い分けるとコストを削減できます。

---

### 7: AWS外のサービスをうまく活用する

AWS以外のAPIを利用している場合、そのAPIが公式で用意しているサービスを用いてコスト削減する手段を模索します。

#### 7-1: 外部のAPIから取得するデータ量を必要十分にする
AWSの外部のAPIから取得するデータを必要十分に調整することで、AWSでの処理の負荷が下がり、コストを下げることができます。

# おわりに
弊社のAWSコスト削減プロジェクトは目下進行中でまだまだ余地はあるはずです。今後も様々模索していく予定です。コメントやご助言ご質問などいただけましたら勉強になりますのでぜひお願いいたします。