ちょっと話題の記事

え、そんなに!?意外と知らないAWSでお金がかかるポイント5選!!第3弾

2020.02.28

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

「でかいインスタンスを建てればAWSの料金が高くなっていく…。」
「大量購入すればお金が飛んでいく…。」

こんにちは(U・ω・U)
AWS事業部の深澤です。

さて僕はこの前このような記事を公開させていただきました。

どちらも大変ご好評いただき、本シリーズも第3弾となりました。いつも読んでいただいている皆さん、有難うございます。是非今回も最後までお楽しみいただけますと幸いです。それでは、いつも通り最初に注意事項を申し上げておきます。

注意

  • 今回ご紹介するものは実際に検証したものではありません。AWSの料金表を確認して、実際このくらい溶けるのではと計算した理論値になります。
  • 日本円のレートは執筆時現在(2020年2月末)のレートとなります。
  • リージョンは東京です。
  • それぞれがどういったサービスなのか、細かい話は割愛します。
  • ここで取り上げたサービスが高いとか悪いとかそういうことを言いたいブログではありません。やはりサービスなので使い方によってはコストダウンになります。そのサービスを利用することによってかかるコストと削減できるコストの費用対効果をよく検討してからサービスをご利用ください。
  • 本ブログの検証は大変危険です。よくお財布を確認してから検証してください。

ポイント5選

AWS Lambda

さて、安くて使いやすいことでお馴染みのAWS Lambda(以降、Lambda)。書いたコードをそのまま実行できる手軽さが人気のサービスです。まずは料金を整理しておきましょう。

Lambdaは実行(リクエスト)回数と、どのくらいメモリを関数に対して割り当てて、どのくらい長くの時間実行したかで料金が変わります。なんとLambdaは100万件/月の無料リクエスト及び400000GB-秒のコンピューティング時間という無料利用枠が無期限なのだから驚きです。しかも使いやすいんですよね。EC2で考えたら関数を実行するためにインスタンスを建てて、そこにログインして実行環境を整えてようやく実行できますが、Lambdaの場合はコードを書いて実行ボタンを押せば簡単に実行できます。しかしこの安さと手軽さで安心してしまい、ついつい使い過ぎてしまうので要注意です。
Lambda関数は手軽にAPIで呼び出せます。例えばpython3.8でLambdaを用意してみて、それをローカルのPCからAWS CLIで呼び出してみました。

time aws lambda invoke --function-name mySimpleLambda response.json
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}
aws lambda invoke --function-name mySimpleLambda response.json  
0.36s user 
0.14s system 
78% cpu 
0.632 total

呼び出しから応答までたったの0.6秒でした。ちなみに処理時間は1msほどです。

仮にこのような処理がアプリケーションに含まれていて、何らかのバグが発生し無限ループに陥ったら…と考えると大変恐ろしいですね。今回のケースで0.6秒おきにLambdaのinvokeを実行したと仮定して、どのくらいで無料枠を使い切るか計算してみましょう。

100万リクエスト × 0.6 = 60万秒
60万秒 = 1万分 = 166.7時間 = 6.9日

たったの約1週間で無料枠(100万件/月の無料リクエスト)を全て使い切る計算になります。仮にこれが1ヶ月(5週間)放置されてメモリが128MBの状態で回り続けた場合の金額を計算してみました。

実行秒数課金

100万(リクエスト)× 4(週間)=400万リクエスト(1週間は無料枠)
400万(リクエスト) × 0.1(ms) = 40万秒実行
128 × 40万 / 1024 = 50000GB-秒

なのでこちらは400000GB-秒の無料利用枠に収まります。一方で実行回数課金はどうでしょうか。

実行回数課金

400万リクエスト × 0.2USD / 1000000 = 0.8USD

0.8USD(87.15円)かかる計算となりました。さらにLambdaは特に同時実行数を制限していなければ並列で処理が行えます。アカウントレベルでの同時実行制限は1000です。例えばこんな感じでスクリプトを投げると並列でLambdaが走り、それぞれが課金対象となります。

$ cat exec_parallel_lambda.sh
for i in `seq 1 5`
do
  aws lambda invoke --function-name mySimpleLambda response.json &
done

またLambdaは大変便利なので、AWSのイベント発生時に呼び出すということも可能です。例えばS3にオブジェクトが配置されたらLambdaを実行してという処理も可能です。このような処理の場合、S3にオブジェクトが置かれる度にLambdaが実行されることになるのでLambdaの大量実行に繋がる恐れがあります。特に何も対策を行っていない場合、このようなLambdaの大量実行に気がつくことは難しいでしょう。

対策

LambdaにはInvocationsというメトリクスがあり、これを監視することでどのくらい関数が実行されたかを検知することができます。

可能であれば、Lambda関数の作成とこの監視はセットで考えた方が無難です。その関数毎に分間どのくらい実行されたら異常なのかを事前に考えておき、その閾値を超えたらアラートを発砲する仕組みを作っておきましょう。また最近、Lambdaの同時実行数が細かく確認できるようになりました。併せてこのメトリクスも監視することでLambdaの異常実行に気がつくことができます。詳しくは弊社数枝のブログをご覧ください。

なおLambdaは同時実行制限をかけることも可能です。サービスに影響しない範囲であればこちらの制限を設けることも積極的に検討しましょう。

さらになんと最近、Lambdaにもsaving planがきました!詳しくは以下のブログをご参照ください。

これらを併用することでLambdaをもっとお得に利用することができますので、良かったら検討してみて下さい。

Amazon CloudWatch(Alarm)

こちらは皆さんお馴染みのサービスだと思います。管理しているシステム異常の検知からAutoScaling発動の契機と幅広く利用されているかと思います。しかし、こちらのCloudWatch Alarmは無料ではありません。ちょっとCloudWatch Alarmの料金は複雑なのですが、まずAlarmをセットするメトリクスの種類によって料金が変わります。メトリクスには標準解像度と高解像度という種類があり、標準は1分おきのメトリクスに対するAlarmです。AWSから標準で提供されているメトリクスはデフォルトで標準解像度になります。一方でカスタムメトリクスと呼ばれるメトリクスだと自在に値をプロットすることができます。これにより1分未満の観測が可能になります。これを高解像度メトリクスと呼びます。標準解像度のメトリクスに対するAlarmは10個までは無料枠の対象になります。この無料枠を超えて設定したAlarmの数、もしくは高解像度メトリクスに対するAlarmは無料枠対象外となりますので設定した個数につき次のように料金が発生します。

種類 コスト
標準分解能 (60 秒) Alarmメトリクスあたり 0.10USD
高分解能 (10 秒) Alarmメトリクスあたり 0.30USD

また、最近は異常検出という機能も実装されました。従来はある閾値を超えたかどうかでそのメトリクスを評価しAlarmを鳴らしていましたが最近は過去のデータから値を予測し、異常値が発生した場合にも検知できるといった機能が使えるようになりました。

この異常検出を用いたAlarmを設定する場合には料金は以下のようになります。

種類 コスト
標準解像度アラーム 0.30USD
高解像度アラームの場合 0.90USD

内訳的には異常検出ではそれぞれ3つのAlarm(1つは評価するメトリクス用、残りの2つは予想される動作の上限と下限用)を設定するので、単純に料金が3倍になります。

CloudWatch Alarmは非常に便利な機能ですが設定し過ぎには注意が必要です。AutoScaling用や監視用で作っていくと余裕で100を越えることもあるかと思いますが、この100を全て高分解能で設定するだけで毎月30USD(3300.31円)の出費です。

対策

必要のないCloudWatch Alarmは削除することを検討しましょう。以下の画面から直近のAlarmの履歴を確認することができます。

もちろん、鳴っていないから必要のないAlarmとは言えませんが、そのAlarmの価値を見直す一つのポイントになるのではと思います。閾値の再検討にも有効ですね。あとはAutoScalingに設定しているものは状況に応じてCloudWatch Alarm以外のものを検討するのも有効です。例えばDynamoDBのAutoScalingであれば、オンデマンドキャパシティモードにすることよってスケールを気にする必要は無くなりますし、EC2のAutoScalingであれば負荷が上がる時間を予測してスケジューリングを設定するという方法も考えられます。むしろ急激なアクセスには対応が難しいので予測できるならこちらの方が有効というケースも多いのではと思います。

Amazon CloudWatch(カスタムメトリクス)

さてお次は同じCloudWatchでもメトリクスの方です。先ほど少しカスタムメトリクスについて触れましたが、標準で提供されるメトリクス以外にアプリケーションやエージェントで好きな値をCloudWatchに送りメトリクスを作成することができます。標準だと60秒間隔ですが、こちらのカスタムメトリクスであれば自在に値をプロットできるので、先ほど申し上げた通り1分未満の観測が可能になります。例えば、EC2のメモリやディスク容量の監視については標準でメトリクスが提供されていません。カスタムメトリクスを用いる必要があります。ではこちらのカスタムメトリクスの料金を確認してみましょう。

範囲 コスト (メトリクス/月)
最初の 10,000 メトリクス 0.30USD
次の 240,000 メトリクス 0.10USD
次の 750,000 メトリクス 0.05USD
1,000,000 を超えるメトリクス 0.02USD

これに加えて、カスタムメトリクスの値の送信にはCloudWatchのAPIを用いるのですが、このAPIへのリクエストにもコストが発生します。

APIの種類 コスト
GetMetricData, GetInsightRuleReport リクエストされた 1,000 件のメトリクスごと 0.01USD
GetMetricWidgetImage リクエストされた 1,000 のメトリクスあたり 0.02USD
GetMetricStatistics、ListMetrics、PutMetricData、GetDashboard、ListDashboards、PutDashboard および DeleteDashboards の~リクエスト リクエストされた 1,000 のメトリクスあたり 0.01USD

例えばEC2インスタンスから5つのメトリクスを1秒おきにPutMetricData APIで値をプロットし続けたと仮定すると、最初の10000個のカスタムメトリクスなので1個あたり0.30 USDで合計1.5USD(165.23円)になります。さらに1秒おきにPutMetricData API叩くので1日で432000回のリクエストが発生して、1ヶ月で大凡1296万回のリクエストをすることになります。最初の100万回は無料枠のため免除されますが、残りの1196万回は課金対象です。1000リクエストごとの課金なので11960 * 0.01USDで119.6USD(13174.71円)がコストになります。合計で121.1USD(13339.94円)が毎月のコストとしてかかってくる計算になります。大抵の場合、EC2インスタンスを1台で運用するシステムというのも珍しいと思いますので、その運用しているEC2のインスタンス分課金が発生してしまいます。

対策

カスタムメトリクスは非常に便利な機能ですが、あまり細かくAPIを叩かないようにしましょう。また、根本的にそのメトリクスは必要なのかということの見直しも是非検討いただければと思います。CloudWatchコンソールにあるメトリクスの検索フィールドに NOT AWS と入力することでカスタムメトリクスを検索することができますので、請求が高額な場合にはこちらをご確認いただき、APIへのリクエスト回数を減らすかメトリクスをなくす等のアクションをご検討ください。

AWS PrivateLink

こちらはAWSのサービスをVPC内の通信で使いたい場合にVPCに設定するインターフェイスタイプのエンドポイントです。VPCエンドポイントにはゲートウェイエンドポイントと今回のインターフェイスエンドポイントがあるのですが、ゲートウェイエンドポイントはルートテーブルを編集してターゲットとして使用するタイプのエンドポイントになります。対応しているのはS3とDynamoDBのみですが利用料金は掛からないお得なサービスです。一方で今回取り扱うインターフェイスエンドポイントはサービスを宛先とするエンドポイントになります。エンドポイントはENI(Elastic Network Interface)を持ち、設定したサブネットのIPアドレス範囲のプライベートIPアドレスを持ちます。こちらは有料となっており次のような料金が発生します。

各AZのVPCエンドポイント1つあたりの料金 (USD/時間) 処理データ1GBあたりの料金 (USD)
0.014USD 0.01USD

ミソなのは1つ辺り時間単位で課金されていくことにあります。例えばAWS Systems Managerというサービスがあるのですが、こちらをAWS PrivateLinkで使うことになった場合には以下のエンドポイントを設定しなくてはなりません。

  • com.amazonaws.リージョン.ssm
  • com.amazonaws.リージョン.ec2messages

これに加えてSystems Managerを使用してVSS対応のスナップショットを作成する場合には以下のエンドポイントも必要になります。

  • com.amazonaws.リージョン.ec2

さらにさらにSession Managerを使用してインスタンスに接続する場合には以下のエンドポイントも必要になります。

  • com.amazonaws.リージョン.ssmmessages

これらを全て使用したとすると1ヶ月(30日)合計で40.32USD(4432.84円)がかかります。これに加えて通信量が上乗せされます。さらに他のサービスのAWS PrivateLinkも…となると意外と月額の料金が大きくなってしまいがちです。

対策

必ずしもVPC内部からの通信でなければならないケースもそんなに多くないと思うので、通常通りネットワーク経由での通信も検討されて良いかと思います。例えば先ほどのAWS Systems Managerですが、Private Subnetのインスタンスを対象とする場合にはNatGateway経由でも通信が可能です。確かにVPCの外側を通信することになってしまうのですが、IAMロールで権限制御していますし通信はSSLで暗号化されているので全くセキュリティ対策ができていないわけではありません。ちなみにNatGatewayは先日同じシリーズで取り上げさせていただいた料金注意なサービス(前回の調査結果だと1台辺り1ヶ月44.64USD)なのですが、他のAWS PrivateLink節約及びインスタンスのアウトバウンド通信を確保してくれると考えれば、決して損なサービスではないと思います。

Amazon EBS

こちらはご存知の方も多いのではないでしょうか。AWSの料金が上がってる!?と思われたらまず無駄なEBSがないかを確認される方も多いかと思います。そうです、多くの方が認識されている通りEBSはアタッチされていなくても存在するだけで料金がかかります。発生する料金はEBSの種類によって異なります。

EBSの種類 発生する料金
汎用 SSD (gp2) ボリューム 1 か月にプロビジョニングされたストレージ 1 GB あたり 0.12USD
プロビジョンド IOPS SSD (io1) ボリューム 1 か月にプロビジョニングされたストレージ 1 GB あたり 0.142USD、さらに 1 か月にプロビジョニングされた IOPS あたり 0.074USD
スループット最適化 HDD (st1) ボリューム 1 か月にプロビジョニングされたストレージ 1 GB あたり 0.054USD
Cold HDD (sc1) ボリューム 1 か月にプロビジョニングされたストレージ 1 GB あたり 0.03USD

対策

不要なEBSに対しても課金が発生してしまうので、まずEC2が消えたらEBSもセットで消えるようにDeleteOnTermination属性にはtrueを設定することを検討しましょう。デフォルトではtrueです。こうすることで不要なEBSの発生を予防することができます。また、「インスタンスを一時停止していてしばらくしたらまた使いたい」といった要望の場合にはEBSをスナップショットにしてしまって、EBS自体は削除してしまうと節約になります。EBSのスナップショットの料金は1カ月で1GBあたり0.05USDで上記のEBSに比べて安いのがお分かりいただけるかと思います。

最後に

いかがでしたでしょうか!実は毎回のサービス選定は皆様からいただいているはてブやTwitterのご感想やリクエストを参考にさせていただいている部分もかなり大きいです。また今回も様々なご意見いただけると幸いです。

また、請求が来てから気づくのではなく、監視しておいて早めに異変を検知できるようにしておきたいですよね!いくつか参考になりそうな弊社ブログをピックアップしましたので良かったら参考にしてみて下さいm(_ _)m
AWSサービス毎の請求額を毎日Slackに通知してみた
支払アカウントからリンクアカウントのBilling Alertを設定する

以上、深澤(@shun_quartet)でした!