AWSサーバレス環境における必要最低限の監視設定 ( ECS + Fargate 編 )

AWSでちょっとしたプロダクト（MVP）をECS+Fargateが開発したようなケースでアプリケーションを運用開始したときに、とりあえずそこまで手間はかけたくないけど最低限の監視はしたいという場合のために、箇条書き程度ですが、必要設定項目を整理してみました。

もしこういういった観点も必要だよねというのがありましたらご指摘いただけますと幸いです。

# 前提条件

- ECS + Fargate 環境でアプリケーションを運用する環境
    - EC2を利用したサーバー運用がないこと
- ECS Serviceに対してAuto Scaling Groupが適用されていること
- アプリケーションの要件的に 24/365監視を専属のインフラチームが対応するほどではないこと
    - 夜間にアラートがなったら PagerDuty等のインフラチームのメンバーの電話を鳴らすような仕組みは今回は対象外です
- インフラの監視にはあまりコストはかけたくなく、監視に関するツールはAWS内になるべく閉じたいこと
- [CloudTrail](https://aws.amazon.com/jp/cloudtrail/), [AWS Config](https://aws.amazon.com/jp/config/)の設定が有効であること
    - 後述するGuardDutyを使用するためには、AWSリソース操作の証跡を残す必要があるため

# セキュリティ監視

- [Trusted Advisor](https://aws.amazon.com/premiumsupport/technology/trusted-advisor/) で警告が無いかを定期的に確認します
    - 1ヶ月に一回ぐらいは、IAM Userの使用状況や設定状況を定期的に棚卸しをします
- [GuardDuty](https://aws.amazon.com/jp/guardduty/)で異常な通知を受けた場合は対応します
  - GuardDutyはAWS ChatbotによるSlack通知設定が可能なため、基本的には異常時にSlack通知が飛ぶようにしてそこだけ見ていれば大丈夫なようにします
  - 参考: [AWS ChatBotでGuardDutyアラートをSlack通知](https://qiita.com/fa60393/items/2ced01ef4a276f675a91)
- [Personal Health Dashboard](https://docs.aws.amazon.com/ja_jp/health/latest/ug/getting-started-phd.html)でインシデントが発生した場合は対応します
  - Personal Health Dashboard はAWS ChatbotによるSlack通知設定が可能なため、基本的には異常時にSlack通知が飛ぶようにしてそこだけ見ていれば大丈夫なようにします
  - 参考: [AWS Chatbot を使って AWS Personal Health Dashboardの通知をいい感じにSlackに通知する](https://engineer.crowdworks.jp/entry/2019/09/17/125955)

# 外形監視

- 以下の観点でサービスが正しく動作しているか、ユーザー影響の把握のための監視をおこないます
    - 5xxステータスコードを返していないか
    - レスポンスタイムに異常無いか
- [Cloudwatch Synthetics](https://ap-northeast-1.console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1#synthetics:) でアプリケーションのエンドポイントの外形監視を行います
  - Canaryを作成するとblueprintが発行されるので、timeout値を定義修正してレスポンスタイムが一定値を超えた場合をエラーとするように任意で変更します
  - 異常時はCloudwatch alermイベントが発行されるのでSNSで通知を受け取ってLambda経由でslackに通知します
  - なお、Cloudwatch alermのイベントをSNS経由でLambdaからslack通知をする際は [blueprint](https://ap-northeast-1.console.aws.amazon.com/lambda/home?region=ap-northeast-1#/create/function/configure/blueprint?blueprint=cloudwatch-alarm-to-slack-python)を使用しますが、通常のCloudwatch alertのイベントのメッセージの構造が微妙に違うので以下のように修正します。

```diff
-    alarm_name =  message['AlarmName']
-    new_state =  message['NewStateValue']
-    reason = message['NewStateReason']
+    alarm_name =  message['detail']['alarmName']
+    new_state =  message['detail']['state']['value']
+    reason = message['detail']['state']['reason']
```

# リソース監視

- マネージドなリソースでもCPUやストレージなどリソース制限があるものに対して監視をおこないます
  - 例えばRDSのStorageのオートスケーリングが有効の場合はコスト面だけ監視していれば大丈夫かと思います
  - Cloudwatch Metricsでひとつひとつの監視項目にたいしてCloudwatch Alermのイベント設定をおこないます
  - Cloudwatch alermをSNSで受け取って lambda経由でslackに通知します
- ECRのイメージスキャンを有効にして、脆弱性の監視を行います
    - 参考: [Amazon ECRのイメージスキャン結果をSlackに通知する](https://qiita.com/hayao_k/items/116e5540b2bf0c2a2c9d)

# アプリケーション監視

- [Sentry](https://sentry.io/)でアプリケーションのエラー監視を行います
  - アプリケーションのエラー監視だけはAWSのサービスだけだと効率よく検知、分析ができないので外部サービスを利用します
  - Sentryはチーム利用は最低料金は月26ドルですが、複数のPJを跨って使用が可能なので、会社でまるっと契約して利用すると効率よく低コストでアプリケーションのエラー監視ができるかと思います
  - 個人のPJの場合は無料枠でも利用ができます
  - 基本的には Slack channel に異常時に通知が飛ぶようにできるので、そこだけ見ていれば大丈夫なようにしておきます
- アプリケーションのログはCloudWatch logsで閲覧できるようにしておきます
    - 障害発生時の調査材料としてアプリケーションのログは CloudWatch logsで見れるようにしておきます

# コスト監視

- コストが必要以上にかかっていないかを確認します。
    - PJによってはインフラの予算が決まっていると思うので、料金が上回りそうな場合は通知を受け取るような仕組みを作っておきます
    - 参考: [AWSサービス毎の請求額を毎日Slackに通知してみた](https://dev.classmethod.jp/articles/notify-slack-aws-billing/)

# 参考

- [DevSecOps on AWS](https://d1.awsstatic.com/events/jp/2018/summit/tokyo/aws/35.pdf)
- [AWS で実現する攻めのシステムモニタリング | AWS Summit Tokyo 2019](https://www.youtube.com/watch?v=9MNMGqnYo68&feature=youtu.be)
- [クラウド環境におけるモニタリングの重要性について](https://pages.awscloud.com/rs/112-TZM-766/images/C3-04.pdf)