AWS利用料金が一定の金額を上回ったらEC2/RDSを強制シャットダウンしたい

AWS利用料金が一定額を超えた際にEC2/RDSを強制シャットダウンしてコスト増大を防ぎます
2021.06.24

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。
ご機嫌いかがでしょうか。
"No human labor is no human error" が大好きな ネクストモード株式会社 の吉井です。

チームメンバーに対して開発検証を自由にさせてあげたい、しかし、AWS 利用料金をある程度で抑えたいという要望をよく伺います。
Budgets で通知はしているけど料金削除までは手をつけられてない現状を嘆く声も頂戴します。

ということで、Budgets 通知をトリガーに EC2/RDS を強制シャットダウンする仕組みを作りました。
GitHub で公開しているので詳しくはこちらを参照ください。

概要

予め決められた AWS 利用料金 (月額) に達すると起動している EC2 インスタンスと RDS インスタンス、Aurora クラスターをシャットダウンします。
AWS 利用料金上限と三段階のしきい値を決定し CloudFormation テンプレートをデプロイすると以下のリソースが作成されます。

image

注意点

起動している EC2/RDS を強制的にシャットダウンします。

シャットダウン中でも各種ストレージや EIP など料金が発生するリソースもございます。
それは手動で管理をお願いします。

RDS はシャットダウン後、8日で自動的に起動します。
料金を発生させたくない場合は手動で削除をお願いします。

環境構築

こちら を clone、または、ダウンロードします。

すべて Linux Bash で操作を行う前提です。
Windows や Bash 以外で操作を行う場合は適宜読み替えていただくか、CloudShell、Cloud9 をご検討ください。

環境変数のセットアップ

環境変数をセットアップします。

環境変数名
MYS3BUCKETNAME lambda zip をアップロードする S3 バケット名
MYS3BUCKETSTACKNAME 上の S3 バケットを作成するための CloudFormation スタック名
DEPLOYSTACKNAME 環境一式をデプロイするための CloudFormation スタック名
Amount 月額利用料金の上限値、USD で指定
Actual1 第一段階のしきい値、上限値の n %
Actual2 第二段階のしきい値、上限値の n %
Actual3 第三段階のしきい値、上限値の n %
EmailAddress しきい値超過の際に通知を送るメールアドレス

値を変更して以下のコマンドを実行します。

cd cfn
export MYS3BUCKETNAME=<your bucket name>
export MYS3BUCKETSTACKNAME=<your stack name>
export DEPLOYSTACKNAME=<your stack name>
export Amount=100
export Actual1=50
export Actual2=75
export Actual3=100
export EmailAddress=<your email address>

Create S3 Bucket lambda upload

ローカルで zip した lambda コードを格納する S3 バケットを作成します。
環境変数をセットアップした同じターミナルで以下のコマンドを実行すると S3 バケットが作成されます。

aws cloudformation deploy  \
  --stack-name ${MYS3BUCKETSTACKNAME} \ 
  --template-file lambda-bucket.yml \
  --parameter-overrides S3BucketName=${MYS3BUCKETNAME}

S3 バケットが作成されたことを確認して次の手順へ進みます。

CloudFormation Package

Lambda をパッケージ化します。

aws cloudformation package \
    --template-file aws-cost-saver.yml \
    --s3-bucket ${MYS3BUCKETNAME} \
    --output-template-file packaged-template.yml

CloudFormation Deploy

packaged-template.yml が正しく作成されていれば
次のコマンドでデプロイします。

aws cloudformation deploy \
  --template-file packaged-template.yml \
  --stack-name ${DEPLOYSTACKNAME} \
  --parameter-overrides Amount=${Amount} EmailAddress=${EmailAddress} Actual1=${Actual1} Actual2=${Actual2} Actual3=${Actual3} \
  --capabilities CAPABILITY_NAMED_IAM

作成されるリソース

作成されたリソースをマネジメントコンソールから確認してみます。

Budgets

Lambda

SNS

まとめ

利用料金のうち大きな割合を占めることが多い EC2 と RDS をシャットダウンする Function を作ってみました。
サンドボックス環境や開発環境など予算が限られている場所で使うことを想定して作成しました。
強制シャットダウンしてしまうので後々揉め事にならないようチーム内調整をしてからお使いください。

以上、吉井 亮 がお届けしました。