💵

AWSのコスト最適化を行い30%程削減した話

2024/01/11に公開

はじめに

こんにちは、アルダグラムのSREエンジニアの okenak です。

今回はスタートアップ企業のAWSコスト最適化に取り組んだ内容を紹介したいと思います。

背景

弊社はグロース期のスタートアップ企業ですがAWSのコストが約1年間で4倍に上昇しました。

これまでは社内の生産性向上や安定したサービスを提供するために、インフラリソースを潤沢に利用してきましたが、急激な円安等の流れもあり今ここにきて見直しが必要なタイミングとなったためコスト最適化に取り組むことにしました。

(上記は補足として開発用と本番用のAWSアカウントの合算の金額です)

コスト最適化のための取り組み

コスト最適化に関してはトレードオフの関係があります。

特に市場に投入するまでのスピードを重視するスタートアップ企業では人的リソースがかぎられるためコスト最適化のための工数は犠牲になりがちです。(それが大きく問題になるまでは)

今回の最適化に関してもかけられる工数は限られているため、なるべく費用対効果が高いものを中心に取り組んでいきました。

AWS CostExplorerで使用状況の分析を行う

AWSのコスト分析は AWS Cost Explorer が利用できます。

各種サービスの利用状況の分析を行ったところ、ECSやRDSなどのコンピューティング費用の増加やEC2その他(NATGateway)の通信費用が大きく占めていることがわかりました。

コスト増加の要因についてですが、過去の経緯で思い当たる点として以下があげられます。

  • ユーザー数の増加に伴うインフラリソース使用料金の増加(スケールアウト/アップ等も含む)
  • エンジニア組織の拡大に伴い開発ラインを増やすためにQA環境を10台以上追加
  • 社内システムへのアクセスのためAWS ClientVPNの導入とVPNの通信量の増加

上記はコスト効率の観点から改善の余地は大幅にありそうな状態だったので、改善できそうな施策をリストアップして費用対効果が高いものから取り組んで行くことにしました。

開発環境を Fargate Spot にして7割引を適用

まず、ECS+Fargateの環境にFargate Spotの導入を行いました。

AWS Fargate Spotの発表 – Fargateとスポットインスタンスの統合 | Amazon Web Services

SpotのデメリットとしてAWSの都合で中断が発生するリスクがあるのですが、社内検証環境など影響が少ないシステムではそこまで問題にならないためFargateからの切り替えを行いました。

キャパシティプロバイダーの設定

ECSでFargate Spotを利用したい場合はキャパシティープロバイダーを設定する必要があります。

CloudFormationで設定する場合は以下の通りです。

  • CapacityProviderStrategyの項目を追加して起動数や割合を設定(参考記事はこちら
  • LaunchType: FARGATEの指定は削除
Type: AWS::ECS::Service
    Properties:
			# LaunchType: FARGATE  ** CapacityProviderStrategyを設定する場合は不要
      CapacityProviderStrategy:
        - CapacityProvider: FARGATE_SPOT
          Base: 1
          Weight: 1
        - CapacityProvider: FARGATE
          Base: 0
          Weight: 0

ECSクラスター側にもCapacityProviderの項目があるためこちらも設定しておきます。

Type: AWS::ECS::Cluster
    Properties:
      ClusterName: !Sub "${EnvironmentName}-kanna-cluster"
      CapacityProviders:
        - FARGATE
        - FARGATE_SPOT
      DefaultCapacityProviderStrategy:
        - CapacityProvider: FARGATE
          Base: 0
          Weight: 0
        - CapacityProvider: FARGATE_SPOT
          Base: 1
          Weight: 1

(上記の設定がないとコンソール上でキャパシティプロバイダーの項目に反映されませんでした)

注意点として、上記の内容を適用すると起動タイプの変更でリプレイスが起こり重複エラーとなるため、先に該当サービスを削除してから反映が必要となりました(ダウンタイムが発生する)

Resource handler returned message: "Resource of type 'AWS::ECS::Service' with identifier 'qa12-kanna-api-service' already exists.

開発環境は検証用にQA環境を10台以上たててたため、全てFargate Spotに切り替えたことでECSコンピューティング費用が70%程度削減できました。

適用後しばらく運用していますが問題なく動いてるためFargate Spotにしてよかったと思います。

開発環境の利用時間外の停止機能の実装

社内の開発環境については深夜や土日は利用されることがないため、自動停止・自動起動する仕組みを実装して、利用されない時間帯のコスト削減を行うことにしました。

仕組みとしては以下となります

  • EventBridgeのスケジューラーで決められた時間になったらLambdaを呼び出し
  • LambdaでECSサービスのdesired countを変更する

実装には AWS SAM というサーバーレスアプリのフレームワークを利用して、インフラの定義・実行コードの管理・デプロイまで簡単にできるようにしています。

上記機能でFargateの月の起動時間を半分に抑えられたため50%程の削減になりました。

AWS ClientVPNからCognito認証へ移行

過去の記事で社内システムのIP制限をSGで行っており、自宅等のリモート先IPを解放する運用作業が大変になってきたため、AWS ClientVPNを利用した固定IP化で問題の解決を行いました。

アーキテクチャとしては以下のようになりNatgateway経由で固定IPからアクセスすることでリモート先の変動するIPを固定化する仕組みです。

ただし、社員数の増加や常時VPNを利用される方が多く出るなど通信量の部分のコストが費用対効果的に微妙な感じになってしまったため、AWSソリューションアーキテクトの方に相談したところ、Cognito認証の仕組みを提案していただいたのでこちらに移行することにしました。

Cognitoの認証ではIAM IdentityCenterを利用したSAML認証を利用しています。
ログイン認証時のセキュリティとしてAWSユーザーにMFAを強制にすることで担保しました。

上記の移行を行ったことでAWS ClientVPNの利用料や通信量を抑えられたため、月15万円程度の削減につながりました。

SavingPlanとリザーブドインスタンスの導入

AWSはデフォルトでは使用量に応じた従量課金のモデルになっていますが、AWSに料金の支払額をコミットすることで割引を受ける機能があります。

コスト分析からECSとRDSのコンピューティング費用が高いことが分かっていたため、弊社の利用ケースに合わせた適切なプランを選んで適用することにしました。

調査内容は以下の通りです

  • SavingPlan
    • AWSアカウントに対して適用で構成の縛りが少ない超柔軟な割引プラン
    • EC2 & Fargate & Lambdaのコンピューティング費用に適用される
    • 購入オプションに全額前払い(63%off)・一部前払い(60%off)・前払いなし(30%off)がある
      • 前払いをする方が最も割引率が高いが購入月にキャッシュが出てくのがデメリット
    • AWS Organizationを利用している場合
      • Savings Plans は主にそれを購入したアカウントに最初に適用される
      • 割引共有の有効化で余剰分を他のアカウントに適用することができる
  • Reserved Instances (RI)
    • AuroraのDBインスタンスの割引はこちらしか選択肢がない
    • RIのデメリットとして構成の柔軟性が下がる点がある
      • インスタンスクラスタイプ①②③が違うと割引が適用されないため変更不能になる

      • ただしサイズに関しては適用されるためスケールアップには対応している

      • mysqlからpostgresに移行したりしても適用されない(ほぼしないと思うが)

      • サーバーを停止や削除しても課金される

        • 開発環境とかで深夜夜間DB停止とか入れるとコスト圧縮効果が減る

弊社の場合は前払いによるキャッシュアウトは避けたかったため以下の内容で適用しました。

  • Saving Plansは3年分割
    • ECS・EC2・Fargateと適用範囲が広くアカウント間共有など柔軟性が高いため3年にする
  • Reserved Instancesは1年分割
    • ファミリーや世代に制限があるため1年単位で見直しを行いたい

まとめ

今回のコスト削減の結果としてAWSアカウント全体で月額費用を30%ほど削減に成功しました。

従来はスピード感を重視してインフラ構築を進めてきたため、コスト最適化のための設計がおざなりになってる部分がありましたが、定期的に振り返っての改善が大事だと痛感しました。

まだ構成変更で削減の余地がありそうな箇所はあるので、今後も継続的に構成の最適化は実施していきたいです。

アルダグラム Tech Blog

Discussion