【SRE】AWS運用コストを年間200万削減（見込み）を達成した話

# はじめに

こんにちは。
GENEROSITYのSREを担当している川口です。

コスト削減。どの組織でも必ず直面する課題ですよね💰

今回はAWSを運用している方向けに、コスト削減の方法を伝授します。

「まだコスト削減何も対応してないよ」という組織においては何かしら得られる情報があるはずです。
また弊社以上にたくさんのアカウント、リソースを運用中であれば、さらなる削減が期待できます。

:::note warn
施策実行直後のため200万円という数値はあくまで見積もりであり、多少の変動があることはご容赦ください。
:::

少しでもみなさんの参考になれば幸いです。

# 結論。コスト削減のためにはこれをやるべし

まずは結論をお話しします。
私はせっかちなので、結論を見るとすぐに「よっしゃやってみよ！！！」と思いますが、後になってつまづかないように、ぜひ最後まで読み進めていただくことをオススメします。
（そしてぜひ♡押してください。励みになります。。🙇）

- 不要アカウント削除
- 未使用/不要リソースの停止、削除
- スペック最適化
- リザーブドインスタンス または SavingsPlans の購入

:::note warn
本記事内で登場する単語については細かく説明しません。後ろにリンクを貼りますのでそちらをご確認ください。
:::

# 弊社のAWS運用状況

- AWSアカウント100以上
- Organizationsでアカウント一元管理
- 開発案件は年に100件を超える
- 案件ごとにAWSアカウント作成
- 短い案件も多く、AWSアカウントのRI購入は見積もりしづらい

#### コスト削減は前々から課題には上がっていたのだが。。

実はコスト削減をしなければ！という意識はあったようなのですが、以下理由から中々手をつけられずにいました。

- 各アカウントの運用状況が一覧化されていない
  - 開発中、運用中、終了などの状況がわからない
- 運用中アカウントへ影響を及ぼすリスクがある
  - 運用中のアカウントに影響をなるべく抑えて切り替えるための準備に時間がかかる
- コスト削減施策実施担当者の不在
  - 元々コスト管理担当やSREチームがありませんでした

今回私が正式にSREチームにアサインしたことで、本格的にコスト削減しよう！となったのがきっかけです。

# コスト削減前の状況

AWS運用状況はこんな感じでした。
（改善の余地があったとご理解いただければ幸いです。）

- 案件終了後に残っているアカウントが存在
- 案件終了後に稼動し続けているリソースが存在
- スペック（インスタンス）の見直しがされていない
- すべてオンデマンドで料金支払い

このような状態から、調査・検討含め他対応と並行しながら**約3ヶ月**で全施策を達成しました。

# 施策決定への道のり

[結論。コスト削減のためにはこれをやるべし](https://qiita.com/KoutaKawaguchi1101/private/1de65a5a4926e929322d#%E7%B5%90%E8%AB%96%E3%82%B3%E3%82%B9%E3%83%88%E5%89%8A%E6%B8%9B%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AB%E3%81%AF%E3%81%93%E3%82%8C%E3%82%92%E3%82%84%E3%82%8B%E3%81%B9%E3%81%97) にて記載した各施策に辿り着いた過程をお話しします。
なぜその施策が必要なのか。にも通ずる内容です。

1. コスト削減のミッションを課せられる。何をしたらいい？
1. まったく分からないのでとりあえず調べてみることに
    - `AWS コスト削減` で検索
1. 様々な単語がヒット！
    - Organizations, 一括請求, 不要リソース, リザーブドインスタンス（以下RI）, SavingsPlans（以下SP） など
1. ひとまずそれぞれの単語の意味について調べてみる
    - RIとSPの違いは何？購入パターンは？見積もり方法は？購入方法は？いくら削減できる？
    - RI, SPを理解することに苦しみました。理解した内容を正しく決済者に伝えなければなりません
    - 以下記事がとても参考になりましたのでぜひご覧ください
    - [Reserved Instance 及び Savings Plan を感覚的に理解するスライドを公開しました](https://blog.serverworks.co.jp/reserved-instance-savings-plan)
1. 色々できそうだけど、まずは現状把握。現時点でクリアしていること。していないこと
    - 弊社では `Organizations、一括請求` はクリアしていました
      - Organizationsでアカウントを一元管理し、一括請求することでボリュームディスカウントを受けられます
      - [一括請求について](https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/con-bill-blended-rates.html#Calculating)
1. 残る施策でできることは何か？
    - 不要アカウント削除
    - 未使用/不要リソースの停止、削除
    - スペック（インスタンス）の見直し
    - RIまたはSPの購入
1. どの順番で実施する？何を優先的に実施する必要があるか
  1. 不要アカウント削除
      - まずはRIの購入検討対象を減らす。アカウントを削除すると、紐づくリソースも削除されます
  1. 未使用/不要リソースの停止、削除
      - ここでも検討対象を減らす
  1. スペック（インスタンス）の見直し
      - RIの購入ではインスタンスファミリーの指定が必要です。その前に最適化しておきたい
  1. RIの購入
      - RIは1年or3年単位で予約購入し、その後はインスタンスの変更ができない
      - RIとSPを比較した結果、弊社状況ではRIが適していると判断しました。詳しくは次のセクションでお話しします

# 施策実施の道のり

それぞれの施策で何をしたのかについてお話しします。

### 不要アカウント削除

1. 何を持ってしてアカウントを不要とみなすか
1. まずはすべてのアカウントを列挙
1. 各アカウントのコストを確認し、極端に低いもの、継続して低コストのものは（仮）削除対象とする
    - CostExplorerというAWSサービスが便利です。どのリージョンで？どのサービスが？いくら？などをグラフ化してくれる
    - [AWS Cost Explorer](https://aws.amazon.com/jp/aws-cost-management/aws-cost-explorer/)
1. アカウント名から削除対象を推測
    - 弊社ではアカウント名の末尾に案件開始日を付与しています（AccountYYYY/MM）
    - また、アカウント作成申請者からGoogleフォーム上で依頼を受けますが、スプレッドシードを同期して出力しているため、いつ、誰が、どのアカウントを申請したかが一覧化されておりこれも参考にしました
1. ある程度は絞り込めたが、本当に削除していいの？一存では決められませんね
1. 組織へヒアリング
    - 管理者は誰？運用中？終了した？いつまで運用予定？
    - 併せて1年以上継続運用するかどうかを確認（RI/SPは1年または3年単位で購入するため）
1. 今度こそ削除していいのでは？いや、データ保管やバックアップの要望があるかも
1. 再度組織へヒアリングを行う
    - データ保管やバックアップ取得したいもの
1. 保管用アカウントを作成し、データを移管
    - EC2 AMIやRDSスナップショットを取得
    - バックアップも大事ですが、復元方法も考えておきましょう
1. 管理者から承認が降りたので、削除します

### 未使用/不要リソースの停止、削除

1. 運用中。継続予定のアカウント内にも不要リソースは存在するよね
1. すべてのサービス、リソースを確認するのは困難なので高コストのリソースを中心に確認
    - EC2, RDS, ECS など
1. ある程度目星をつけて、後は地道にAWSコンソールで確認
1. 組織へヒアリング
    - やはりヒアリング。不要なものは停止/削除していきましょうね。を呼びかけ
    - ある程度期間区切って対応しましょう
1. 管理者と協力して停止/削除

### スペック（インスタンス）の見直し

RIではインスタンスファミリーを指定して購入する必要があるとお話ししました。
不適切なインスタンスを購入すると、1年または3年間インスタンスを変更することができないため（できる方法もありますが割引率が下がります）まずは最適化しようと考えました。
弊社ではGravitonを利用していなかったので、まずはGraviton化することを行いました。
もし時間に余裕があり、変更が可能なリソースであれば負荷テストや使用率を確認した上で、適切なサイズに変更することが理想です。

1. どのサービスのインスタンスの見直しが必要？
    - RIではEC2, RDS, Redshift, ElastiCache, OpenSearch Serviceサービスを対象に購入が可能です
    - コストインパクトの大きいEC2,RDSを見直すことに
1. まずは現状把握。それぞれのリソースでどのインスタンスを使用しているか確認
1. 手作業で確認するわけにはいかないのでツールを使って一括取得
    - 私はGolangでAWS-SDKを使って、複数アカウントの対象リソースの情報（IDやインスタンスなど）を取得するツールを作成しました
    - [AWS SDK for Go](https://pkg.go.dev/github.com/aws/aws-sdk-go)
1. 適切なGravitonインスタンスを選択
    - t2.micro → t4g.microなど
1. インスタンス移行手順を作成
1. 管理者と協力して変更を実施
1. 変更後に正しく動作していることを確認

#### 移行作業者の負担を減らすために

移行対象のEC2, RDSにおいてダウンタイムをなるべく小さくするため `変更` ではなく `移行` の方法で手順書を作成しました。
対象を直接変更するのではなく`複製したインスタンスに切り替える`という考え方です。
（内容をざっくり記載します。より良い方法があるかもしれませんので、参考程度にお願いします。）

- EC2
  - 移行元インスタンスと同様の設定、ボリュームで移行先インスタンスを起動
  - Route53でEC2のパブリックIPをドメイン登録している場合
    - レコードへ登録しているIPアドレスを移行先インスタンスへ変更（切り替え）
  - ロードバランサーのターゲットにEC2を設定している場合
    - 移行先インスタンスをターゲットに登録
    - 移行元インスタンスをターゲットから削除（切り替え）
  - インスタンス内にMySQLを導入している場合
    - 移行元DBのダンプファイルを取得し、移行先DBへリストア（複製）
- RDS（Aurora MySQL）
  - 移行元クラスターのスナップショットを取得し、これをもとに移行先クラスターを復元（複製）
  - クライアントの接続先エンドポイントを移行先へ変更（切り替え）
- 疎通確認
  - 各サービスの切り替えが完了したら、必ず疎通確認を実施しましょう

:::note warn
EC2起動時に指定するアーキテクチャが `x86` か `Arm` により、ボリュームのMOUNTPOINTの名称など違いが存在するため、手順を分けること、検証をすることが重要です。
:::

振り返ると、復旧手順をより充実すべきだったなと感じました。。次回に活かします！

### RIの購入

RIとSPのどちらを購入するか？についてですが、以下ポイントで弊社状況によりRI購入を選択しました。
状況に併せて組み合わせやプランを検討してください。

- 1年以上継続稼働予定のリソースがある
- 1年間インスタンス変更の可能性が低い
- 高い割引率を適用したい

1. どのアカウントに対して、どのインスタンスをいくつ？どのプランで購入する？
1. Compute Optimizerで推奨事項を確認
    - 稼働中のリソースに対して購入方法を推奨してくれます。しかし、これはあくまで稼働中のすべてのインスタンスに対しての推奨事項
    - 弊社ではあるアカウント内においても、1年以上稼働予定のリソースとそうでないものが混在するためこの方法は活用できず
1. そこでAWS Pricing Calculatorや料金表の出番！
    - インスタンスやプランを指定すると、購入金額やオンデマンド料金と比較した削減額を示してくれます
    - [EC2 リザーブドインスタンス料金表](https://aws.amazon.com/jp/ec2/pricing/reserved-instances/pricing/)
1. これもすべて手計算していては大変なので、またまたGolangで自動計算ツールを作成して計算しました
1. アカウントについては[不要アカウント削除](https://qiita.com/KoutaKawaguchi1101/private/1de65a5a4926e929322d#%E4%B8%8D%E8%A6%81%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E5%89%8A%E9%99%A4)にてヒアリングをかけた内容から`1年以上継続利用予定`のアカウントを対象
1. また適用時には正規化係数という概念があるので、最小サイズを組み合わせた購入をするように計算
    - [RIの正規化係数](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/apply_ri.html)
1. すべてを合計して以下を算出
    - 合計購入額は？オンデマンドに対して削減額は？年間でいくらになる？
1. 決済者に承認を取り、無事購入

すべての施策が完了！年間200万円の削減（見込み）達成！🎉

# 開発メンバーとのコミュニケーション

これらの対応を行うには `開発メンバーとのコミュニケーションが必要不可欠` です。

SREは何をやるべきか、どうやるべきかを考えますが、すべて自身で対応できるわけではありません。
対応のため、開発メンバーはスケジュールの中にこれらの対応を組み込み、リソースを削って対応せねばなりません。
（実はここが一番苦労したポイントでもあります）

そこで協力をお願いするにあたり、以下を意識して取り組みました。

- 必ず1ヶ月以上の猶予を持って展開する
- 可能な限り手順書を充実させる（手順書通りに進めればOKが理想）
- いつでもどんな内容でも相談してね（ウェルカム）の姿勢

施策を終えて `（目安）1ヶ月半以上前から情報を頭出しする` ことで、より開発メンバーの心理的負担が軽減できると考えます。

【頭出しがない場合】
（SRE）1ヶ月以内にインスタンス移行よろしく！対応に3人日くらい必要かも！
（開発）いきなり3人日必要と言われても困るなぁ。。どこに差し込めばいいんだろう。。

【頭出しがある場合】
（SRE）来月移行でインスタンス移行しようと思っているよ！対応に3人日くらい必要かも！あとでリソース状況などヒアリングさせてね！
（開発）来月のスケジュールは3人日空けておかないとな。リソース状況確認しておこう！

# 施策検討前に知っておきたいポイント

各施策の調査・検討を始める前に、事前に知っておくことでスムーズになりそうなポイントをまとめてます。
各セクションで登場した単語やリンクのまとめです。

- [AWS Organizations](https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/consolidated-billing.html)：アカウントの一元管理
- [一括請求](https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/con-bill-blended-rates.html#Calculating)：請求をまとめることにより得られるボリュームディスカウント
- [Graviton](https://aws.amazon.com/jp/ec2/graviton/)：Gravitonインスタンス
- [SPとRIの概要](https://blog.serverworks.co.jp/reserved-instance-savings-plan)：SPとRIの違いについて理解する
- [RIの正規化係数](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/apply_ri.html)：インスタンスの割引適用方法
- [AWS Cost Explorer](https://aws.amazon.com/jp/aws-cost-management/aws-cost-explorer/)：コスト管理サービス
- [AWS Compute Optimizer](https://aws.amazon.com/jp/compute-optimizer/)：最適化提案サービス
- [AWS Pricing Calculator](https://calculator.aws/#/addService)：料金計算ツール
- [EC2 リザーブドインスタンス料金表](https://aws.amazon.com/jp/ec2/pricing/reserved-instances/pricing/)：EC2のRI計算に利用

# さいごに

ここまでお読みいただきありがとうございます。

私がさいごみなさんにお伝えしたいのは
SREの活動は`開発メンバーとSREが一丸となって取り組む`ものであるということです。

先ほどもお話ししましたが、すべての対応をSREのみで実施することは不可能であり、必ず開発メンバーとのコミュニケーションが必要となります。
`組織をより良くするために、お互いが同じ方向へ進むためのコミュニケーション`をしましょう。

長くなりましたが、少しでもみなさんの参考になれば幸いです。
ここまで読んでくださりありがとうございました！