AWSリザーブドインスタンスの購入時にチームメンバーのレビューを通す

システムプラットフォームチーム所属の id:k1s1eeeです。

この記事は、はてなのSREが毎月交代で書いているSRE連載の12月号、かつはてなエンジニア Advent Calendar 2024 の12月26日の記事です。

SRE連載 11月の記事は id:rskmm0chang さんの「GitHub ActionsのSelf Hosted Runner向けにImage Cache Proxyを導入しました」でした。

はてなエンジニア Advent Calendar 2024 12月25日は id:yujiorama さんの「Implementing Google BigQuery REST API (v2) jobs.query」でした。

AWS リザーブドインスタンス とは

AWS リザーブドインスタンス(以下 RIと表記します)は、AWSの使用料金を節約するためのオプションで、AWSの提供するいくつかのサービスで利用することができます。

例えば EC2の場合は、1 年間または 3 年間の期間で特定のインスタンスを予約購入することで、オンデマンド料金で使い続ける場合と比較して最大72%の割引を受けることができます。

サービス、インスタンスの種類によって割引率や適用条件が異なりますので、各サービスの最新ドキュメントをご確認ください。

はてな でのRI運用

現在、はてな ではシステムプラットフォームチーム が社内で発生するインフラにまつわるコストを統括しています。

コスト削減に大きな効果のある RI の購入については、各プロダクトチームからの要望をシステムプラットフォームチームがとりまとめて管理(購入、更新)する運用となっています。

これまでの購入フローでは、プロダクトチームから申請された内容を、システムプラットフォームチームのチームメンバーがマネジメントコンソールのWEB画面を用いて慎重に操作を行って購入するというオペレーションを行っていましたが、WEB画面での操作では下記のような懸念がありました。

  • オペレーターの操作誤りや項目の選択ミスで、誤った種類のRIを購入してしまう危険性がある。
  • RIで予約購入を行えないサービスもあるため、担当者が時間に合わせて操作をしなければならない。

これらの懸念について まずは小さく改善を始めたいという点から、AWS CLIを取り入れる事によって下記の効果を期待して導入することとしました。

  • 実行するコマンドのパラメータを複数人でレビューできるようになり、ミスの抑止や安全性の向上を期待できる。
  • 時間に合わせて購入したい場合に、タイマーを使った購入操作の自動化をしやすくなる。

以下に事例として Amazon RDS RI の購入フローをご紹介します。

Amazon RDS RI を レビューを通してAWS CLIで購入するフローの事例

Amazon RDS RIの購買方法として、WEBのマネージドコンソールから購入する方法の他に、AWS CLIとAPIでの購入方法も提供されています。

今回は開発などは行わず、小さく始めたかったのでAWS CLIでの購入方法を選択し下記のフローで進める事にしました。

  • プロダクトチームからRI購入の要望を受け付ける。
  • ReservedDBInstancesOfferingIdを調べる。
  • 申請内容をもとに購入コマンド用の引数を用意する。
  • チームメンバーでレビューする。
  • レビュー済みのコマンド引数を用いてAWS CLIでRI購入を実行する。

プロダクトチームからRI購入の要望を受け付ける

プロダクトでの一定期間の継続稼働が見込まれるDBインスタンスのスペックを申請してもらいます。

実際の運用では システムプラットフォームチームが用意したGoogle スプレッドシート上に、各チームから必要なスペックや台数、発生する金額の概算などを申請し、シートの情報をもとに購入準備を行っています。

今回は下記のスペックのAmazon RDS RI購入を例とします。

項目
リージョン ap-northeast-1
DB エンジン MySQL
DB インスタンスサイズ db.t4g.medium
マルチAZの有無 マルチAZあり
数量 1台
期間 1年 (31536000秒)
支払い方法 全額前払い

Amazon RDS RIで気をつけたい点は下記のドキュメントで確認する事ができます。

AWS CLIでのRI購入に必要なパラメータ類を用意する

Amazon RDS RIをAWS CLIで購入するためには、下記の 2ステップが必要になります。

  1. ReservedDBInstancesOfferingIdを調べる。
  2. 購入コマンドの引数を用意する。

詳細は下記のドキュメントで確認できます。

ReservedDBInstancesOfferingIdを調べる

希望するスペックに対応するReservedDBInstancesOfferingIdをaws rds describe-reserved-db-instances-offeringsコマンドで検索する事ができます。

aws rds describe-reserved-db-instances-offerings \
--region ap-northeast-1 \
--db-instance-class db.t4g.medium \
--product-description mysql \
--multi-az \
--duration 31536000 \
--offering-type 'All Upfront'

コマンドの実行結果として下記のようなjsonを得る事ができます。

{
    "ReservedDBInstancesOfferings": [
        {
            "ReservedDBInstancesOfferingId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
            "DBInstanceClass": "db.t4g.medium",
            "Duration": 31536000,
            "FixedPrice": 1289.0,
            "UsagePrice": 0.0,
            "CurrencyCode": "USD",
            "ProductDescription": "mysql",
            "OfferingType": "All Upfront",
            "MultiAZ": true,
            "RecurringCharges": [
                {
                    "RecurringChargeAmount": 0.0,
                    "RecurringChargeFrequency": "Hourly"
                }
            ]
        }
    ]
}

jsonキーReservedDBInstancesOfferingIdを確認できます。 実際の運用ではjqなどを利用して必要なキーと値を抽出すると見やすくなります。

購入コマンドの引数を用意する

RIの購入にはaws rds purchase-reserved-db-instances-offeringコマンドを使用します。

purchase-reserved-db-instances-offeringで必要になるコマンド引数は 主に下記です。

--region ap-northeast-1 \
--reserved-db-instances-offering-id <value> \
--db-instance-count <value> \
--reserved-db-instance-id <value> \
  • regionは予約先リージョンを明確に指定します。
  • reserved-db-instances-offering-idは前の手順で検索したReservedDBInstancesOfferingIdを指定します。
  • db-instance-countは予約するインスタンス数を数値で指定します。
  • reserved-db-instance-idは予約リソースを追跡するための識別子です。
    • 管理上で都合の良いものを指定すると良いでしょう。弊社では購入時期や、管理チームが判別できるような命名規則でIDを生成して付与しています。

今回の引数は下記のようにしました。

aws rds purchase-reserved-db-instances-offering \
--region ap-northeast-1 \
--reserved-db-instances-offering-id "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
--db-instance-count 1 \
--reserved-db-instance-id "2024-12-26-ProductionName" \

チームメンバーでレビューする

主に下記の2つの観点をレビューします。

  • ReservedDBInstancesOfferingIdは適切か。
  • 購入コマンドの引数は適切か。

ReservedDBInstancesOfferingIdは適切か

aws rds describe-reserved-db-instances-offeringsコマンドに--reserved-db-instances-offering-id <value> 引数でReservedDBInstancesOfferingIdを与えると、対応するRIの予約内容をjsonで確認する事ができます。

aws rds describe-reserved-db-instances-offerings \
--region ap-northeast-1 \
--reserved-db-instances-offering-id "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \

コマンドの実行結果として下記のようなjsonを確認できます。

{
    "ReservedDBInstancesOfferings": [
        {
            "ReservedDBInstancesOfferingId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
            "DBInstanceClass": "db.t4g.medium",
            "Duration": 31536000,
            "FixedPrice": 1289.0,
            "UsagePrice": 0.0,
            "CurrencyCode": "USD",
            "ProductDescription": "mysql",
            "OfferingType": "All Upfront",
            "MultiAZ": true,
            "RecurringCharges": [
                {
                    "RecurringChargeAmount": 0.0,
                    "RecurringChargeFrequency": "Hourly"
                }
            ]
        }
    ]
}

このjsonと、プロダクトチームからの申請シートを比較することで、ReservedDBInstancesOfferingIdが正しいかをレビューできます。

項目 対応するjson key
DB エンジン MySQL ProductDescription
DB インスタンスサイズ db.t4g.medium DBInstanceClass
マルチAZの有無 マルチAZあり MultiAZ
期間 1年 (31536000秒) Duration
支払い方法 全額前払い OfferingType

購入コマンドの引数は適切か

ReservedDBInstancesOfferingIdの確認と合わせて、下記の観点をプロダクトチームからの申請シートと比較してレビューします。

  • regionのリージョン指定は誤っていないか。
  • reserved-db-instances-offering-idで指定しているReservedDBInstancesOfferingId は誤っていないか。
  • db-instance-countの数量が誤っていないか。
  • reserved-db-instance-idで指定している追跡用のIDは適切か。
--region ap-northeast-1 \
--reserved-db-instances-offering-id "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
--db-instance-count 1 \
--reserved-db-instance-id "2024-12-26-ProductionName" \

reserved-db-instances-offering-idの指定はもちろんですが、ここで特に気をつけたいのは、リージョンの指定と数量が合っているかです。

  • リージョン指定が誤っていると、サービスによっては希望したリージョンでRIが適用されない場合があります。
  • 数量の指定を誤ると予定していた台数と違う台数で買ってしまったがキャンセルできない。という誤発注を引き起こします。

一度購入したRIはキャンセル出来ませんので、とても緊張感のある引数となっています。

レビュー済みのコマンド引数を用いてAWS CLIでRI購入を実行する

チーム内でレビューを通過し、パラメータ類に問題がない事を確認した後はaws rds purchase-reserved-db-instances-offeringコマンドを実行することで、マネジメントコンソールでのRI購入と同様にRIを購入する事ができます。

コマンドを実行すると即座にRI購入が行われ、かつキャンセル不可なのでとても緊張感のあるコマンドです。

aws rds purchase-reserved-db-instances-offering \
--region ap-northeast-1 \
--reserved-db-instances-offering-id "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
--db-instance-count 1 \
--reserved-db-instance-id "2024-12-26-ProductionName" \

購入が成功すると、請求連絡先へメールで請求書が届きますので実行内容を確認できます。

まとめ

以上が 試験的に取り入れたAWS CLIを用いてRI購入を行う作業フローとなります。

冒頭で掲載しましたが、WEB画面操作でのRI運用フローには下記のような懸念がありました。

  • オペレーターの操作誤りや項目の選択ミスで、誤った種類のRIを購入してしまう危険性がある。
  • RIで予約購入を行えないサービスもあるため、担当者が時間に合わせて操作をしなければならない。

これらはAWS CLIを用いた運用フローに変更することで、複数人でレビューを行えるという効果を達成する事ができました。 今回は、コマンドでの購入は手動で行いましたが、今後はタイマーでの自動化など試していきたいと思っています。

RIの購入タスクは 大きな金額が発生する事が多いが キャンセルする事ができない責任の大きな作業です。 今後も、安全にそして確実にタスクを遂行するための仕組み作りを模索したいと思います。

以上、AWSで RI購入作業を担当される方の参考になれば幸いです。

はてなエンジニア Advent Calendar 2024 の明日の担当は id:onishi さんです。