本当にあったAWSでやらかした話と対策😭

# 概要
みなさんこんにちは🎄
「[フォトリ](https://photream.com/)」という家族写真の撮影サービスを運用している会社でCTOをしてるカイトズズキと申します。

この記事では、先日会社のAWSで割と高額の請求が来てしまい😭死にたくなる思いをしたので、そのお話についてしていきます。

AWSは便利だけど、お金使いすぎたりしないか不安になりますよね。
特に僕はそんなにAWSには詳しくない人間なので、なおさらドキドキです。

この記事を通して、僕がやっちまった失敗をみなさんに知ってもらい、
同じような失敗をする人が1人でも減ることを祈ってます🙏

# やらかした話
### やらかしレベル
まず、結果としてどれくらいやらかしたかと言うと、
普段の使用料金以外に、
- `Lambda` で **10万円** くらい
- `S3` で **30万円** くらい
の請求が来てしまいました、、、

普段は数万円程度で2つのWebサービスを運用しているため、
最初に気づいたときは驚きすぎて理解に苦しみました、、、笑

なお、結果的に `Lambda` の方はAWS様にご返金いただきました。
本当に神です、これからも一生ついていきます😭

### 何が起きたのか
まず最初に述べたいのは「しょうもないミス」です。
それだけにショックは大きいのですが、基礎が全てですね。

まず、今回事件が起きたシステムの概要図です。
<img width="658" alt="スクリーンショット 2019-12-03 19.53.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81183/63c173e3-ef0b-3a69-2ec2-d0b16a5df16e.png">

1. ユーザーが画像を送信
2. 送信された画像を受け取り、S3にアップロード
3. S3の特定の場所（フォルダA）にファイルがアップロードされたときに、Lambda関数が発火
4. 画像を加工し、S3にアップロード（フォルダB）

この一通りの流れで、
- ユーザーがアップした元画像 → **フォルダA**
- 加工された画像 → **フォルダB**
という状況が完成します。

サービスの仕様上、さまざまな画像ファイルを取り扱うため、
このなんとも便利なシステムを僕らはいろんな場所で活用しておりました。。。

**しかし！！**

ある日事件は起きました。
新しくLambda関数を作成した際に、
**フォルダAとフォルダBに、同じフォルダを指定してしまったのです。**

言い換えると、Lambda内で加工した画像を加工前の画像があるフォルダに再アップする仕様にしてしまったのです。

（分かりにくい日本語ですみません🙇）

何が起きるかおわかりでしょうか？

先ほどの説明の 4 を実行した後に、再度 3 が実行されてしまい、3 → 4 → 3 → 4 ・・・ という無限ループが起きてしましました。

普通に考えればすぐに気づくことなのですが、、、

これにより `Lambda` 関数がたくさん実行され、 `S3` にたくさん画像がアップロード/ダウンロードされ（具体的には GET と PUT のリクエストがたくさんされ）、無事に高額の請求がきました😇

### なぜ高額になったのか
ただ、ミスった設定をしたことが問題ではなく、「すぐに対処できなかった」ことが本当の問題でした。
今回の件は、最初の無限ループが始まってから事件発覚までに約1週間もかかりました。

それもたまたま今月の請求をチラ見したときに気づいたので、気づくのにもっとかかっていた可能性すらあります。

この後の「対応・対策」の部分で、このあたりを詳しくお話します。

# 対応・対策
今回の件を経て、いくつか対応や対策をしたので、軽くご紹介します。
皆さんも同じような目に遭わないよう、ちゃんと対策できてるか振り返ってみてください。

（他にもこんな対策あるよ！みたいなのあれば是非たくさんコメントください！！）

### 対応
「対策」の前に「対応」です。

事故後に行った「対応」としては、

- 事故ったLambdaの設定を修正
- AWSに問い合わせ（ごめんなさい返金してくださいお願いします）

といった感じです。

あからさまな自爆で返金してもらうのは本当に申し訳なかったですが、
AWSの中の人に「たぶん返金できるよ」と教えてもらったので、勇気を持ってごめんなさいしました。

また、今回の対応をするにあたり、以下の記事を参考に障害報告を作成しました。

[エンジニアなら知っておきたい障害報告&再発防止策の考え方 - Qiita](https://qiita.com/hirokidaichi/items/f9f4549c88aaf8b38bda)

これまでメンバーが数人の会社ということもあり、ほとんどの報告を口頭で行っていましたが、
この記事を参考に報告書を書いてみたところ、状況や思考がうまく整理され、かなりスッキリしました。

わざわざ文章書くのはめんどくさく感じますが、
これは今年一番のオススメなので、最近やらかした人もこれからやらかす人も是非参考にしてみてください！

### 対策

今回の諸悪の根源は、「事故ったこと」ではなく「事故に気づかなかったこと」だと思ってます。
なんなら気づくのに時間がかかったからこそ、ちょっとしたミスが事故になった、とも言えます。

AWS様にお問い合わせした際、以下のような返事を頂きました。

> 意図しない課金が発生を防ぐため、
CloudWatch [参考1] にて請求アラートを作成いただき利用状況をモニタリングいただくこと、
AWS Budgets [参考2] を利用いただくことで予想されるコストがお客様の作成した予算を上回る場合や予算を超えた場合にアラートを通知するよう設定いただくことをおすすめしております。
> 
> お手数ではございますが、下記の参考情報をご確認いただき、ご設定をいただきますようお願い申し上げます。
> 
> [参考1] https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/monitor_estimated_charges_with_cloudwatch.html
> [参考2] https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/budgets-managing-costs.html

これらを設定することにより、請求額が異常な値になるその前に気づくようになることができます。
やって当たり前の設定なのですが、それをサボっていたのです。。。
もし僕と同じようにサボっている人は、この機会に是非。

また、上記に加えて、 `CloudWatch` を用いて、`Lambda` 関数の実行回数（`Invocations`）にしきい値を設定し、実行されまくったときに通知がくるように設定しました。

<img width="285" alt="スクリーンショット 2019-12-03 20.52.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81183/9562be41-91df-07e2-c1a8-d163ab379954.png">
↑こんな感じ

関数毎に値を変えて設定しました。

また、各種通知はメールに送信されるだけでは見落とすリスクがあるため、
Slackの通知用チャンネルにも自動で投稿されるようにしました。

（ここまで偉そう？に書いてますが、もろもろ対応を手伝ってくれたインターンS君、ありがとう！）

# 最後に

拙い文章ですが、最後まで読んでいただきありがとうございます。

事故ったときはショックのあまり夜も眠れない日々でしたが、
一通り振り返ってみて、すごくいい体験ができたな、と思ってます。

皆さんも是非、たくさん失敗しながら楽しいAWSライフをお送りください！