AWS Well-Architected Labs Operational Excellence 100 Dependency Monitoringメモ

# はじめに

https://www.wellarchitectedlabs.com/operational-excellence/100_labs/100_dependency_monitoring/

:::note warn
記載内容は上記の翻訳ではなく、意訳、要約を含みます。
手順も一部省略している部分もあります。
詳細や正確な手順を知りたい場合は本家サイトを参照ください。

画面スクショは本記事作成当時のものであり、今後のアップデートにより差異が発生する可能性があることをご留意ください。
:::

## Introduction

本ハンズオンではリソースの依存関係監視について学び、メトリクス監視やアラーム設定について学ぶことができます。

## DEPLOY THE INFRASTRUCTURE

多くのワークロードは外部サービス、リソースに依存しています。
そのため、依存するサービス、リソースにデグレや障害が発生し、使用できなくなるとワークロードの機能性に大きな影響が発生します。
これらの依存関係を監視するためアラートや通知を設定することで関係者が問題を迅速に認識し、対応することができ、事業継続への影響を最小化することができます。

このハンズオンではOperational Excellenceのベストプラクティスである以下3つの実装例を示します。

- 依存関係のテレメトリーの実装
- ワークロードの異常が発生した場合のアラート
- プッシュ通知の有効化

本ハンズオンで監視するワークロードのアーキテクチャを紹介します。
右側のEC2インスタンスは外部サービスをエミュレートしたものです。50秒間隔でS3バケットにデータを書き込みます。
真ん中のS3バケットはイベント通知機能を有効にしています。バケットにデータが書き込まれると、通知を受け取るよう設定しています。
左側のLambda関数はS3バケットの通知を受け取ったら実行するよう設定しています。

![ArchitectureFirst.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/6749ffb9-bbaf-6cbf-e065-e70e86937b90.png)

### 1.1 Log into the AWS console

AWS管理コンソールにログインしてください。

### 1.2 Deploy the infrastructure using AWS CloudFormation

用意されたCloudFormationテンプレートを使ってハンズオン用スタックを作成します。
必要な部分だけ説明します。

[ここ](https://www.wellarchitectedlabs.com/Operations/100_Dependency_Monitoring/Code/dependency_monitoring.yaml)からCloudFormationテンプレートをダウンロードしてください。

スタック名は今回は`Dependency-Monitoring-Lab`とします。
パラメーターの値は以下の通りに入力します。
`AvailabilityZone`はプルダウンからAZを1つ選択してください。
`BucketName`はアーキテクチャの際に説明したS3バケットのバケット名を入力します。今回は`wa-lab-<あなたの名字>-<日付><時間>`とします。
`LatestAmiId`はデフォルト値にしてください。
`NotificationEmail`は依存外部サービス関連の通知を受け取るアクセス可能なメールアドレスを入力してください。

スタックの作成中に`NotificationEmail`に設定したメールアドレスに確認メールが届きます。
リンク`Confirm subscription`をクリックしてください。

![スクリーンショット 2023-08-18 21.52.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/7f967aea-0a12-88b5-53cd-068b603eb770.png)

以下のような画面が表示されたら購読設定完了です。
購読解除する際はリンク`click here to unsubscribe.`をクリックしてください。

![スクリーンショット 2023-08-18 21.52.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/0597a404-6609-c051-e1dd-95acd3c1f7b4.png)

スタックのステータスが`CREATE_COMPLETE`になったらプロビジョニング成功です。

![スクリーンショット 2023-08-18 21.55.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/8cade094-a830-3c49-ab28-2dce10b2bb17.png)

## UNDERSTANDING METRICS

メトリクスとは、監視対象から取得するシステムのパフォーマンスに関するデータセットを指します。
ワークロードは、リクエスト数やエラーコードなどのアプリケーションメトリクス、CPU使用率、メモリ使用率、ディスク使用率などのインフラストラクチャメトリクスなど、様々なメトリクスを出力するよう設計すべきです。
多数のメトリクスを理解することで、監視に適切なメトリクスを選択することができ、ワークロードと依存関係のある外部サービスの可用性やステータスを理解することができます。

今回のハンズオンでは、S3バケットにデータが書き込まれるとLambda関数が実行されます。
Lambda関数に関するメトリクスを理解することで、依存サービスの健全性を判断するための適切なメトリクスが何かを判断することができます。

AWS LambdaはLambda関数を自動的に監視し、Amazon CloudWatchにメトリクスを送信します。
メトリクスにはリクエスト数、リクエスト毎の実行時間、エラーになったリクエスト数などがあります。
また、これらのメトリクスを活用してCloudWatchカスタムアラームを設定し、メトリクスが変化したら自動で応答するよう設定もできます。

https://docs.aws.amazon.com/lambda/latest/dg/lambda-monitoring.html

LambdaががCloudWatchにデフォルトで送信するメトリクスは以下3種類です。

- 呼び出しメトリクス
- パフォーマンスメトリクス
- 同時実行メトリクス

それぞれどのようなメトリクスを集計するかは[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/monitoring-metrics.html)を参照ください。
また、以下の記事もわかりやすかったです。

https://overworker.hatenablog.jp/entry/2021/02/04/005726

また、公式ドキュメントにも記載があったようにデフォルトではありませんが、`非同期呼び出しメトリクス`という種類もあるのでご留意ください。

https://dev.classmethod.jp/articles/new-lambda-metrics-asynchronous/

さて、今回のハンズオンでは`呼び出しメトリクス`の`Invocations`と`Errors`に注目します。
`Errors`はLambda関数の呼び出しでエラーになった回数です。Lambdaランライムで発生した例外や設定誤りによるエラー、タイムアウトなどがあります。
外部サービスに関する問題を特定するのに重要な指標となります。
外部サービスのパフォーマンスが低下していたり、障害でS3にファイルの書き込みができない場合が考えられます。
Lambda関数の実行自体されなくなる可能性があり、`Errors`の監視だけではこの状態を検出することは困難です。
`Invocations`はLambda関数の呼び出し回数です。外部サービスは50秒に1回S3バケットにファイルを書き込みます。したがって、50秒に1回Lambda関数が呼ばれることになります。
`Invocations`を監視することで想定した間隔で外部サービスが稼働しているのか確認することができます。

では、実際に画面の操作に移っていきましょう。

まず、Amazon CloudWatchのダッシュボードに遷移し、左メニュー`すべてのメトリクス`を選択してください。
検索窓に`WA-Lab-DataReadFunction`と入力し、エンターキーを押下してください。
検索されたもののうち`Lambda > リソース別`リンクをクリックしてください。

![スクリーンショット 2023-08-18 21.59.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/268a5931-36d5-a2d0-df2d-67d3090103b2.png)

利用可能なLambdaのメトリクスの一覧が表示されます。
メトリクス名`Invocations`をチェックすると上のグラフでLambda関数が呼び出された時間と回数を確認することができます。

![スクリーンショット 2023-08-18 22.02.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/07256c96-a0cc-942d-5a53-ff995044cbe0.png)

画面上部にある`Custom`ボタンをクリックし、`Minutes`の`15`を選択してください。
その後、画面中央の`グラフ化されたメトリクス`タブを選択し、`期間`を`1分`に変更してください。
これで、グラフの表示範囲が直近15分間になり、メトリクスの粒度が1分間隔になります。
先ほど説明したように`Invocations`はLambda関数の呼び出し、つまり、S3バケットへのデータの書き込みを表します。
このメトリクスの回数と頻度を監視することで外部サービスの可用性の監視にも繋がります。

![スクリーンショット 2023-08-18 22.05.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/12df318b-c693-18d4-0630-42f593121050.png)

## CREATE AN ALARM

監視すべきメトリクスを特定したので、メトリクスを監視するアラームを作成し、定義したしきい値に基づいて通知を送信するよう設定します。
CloudWatchアラームで上記実現ができます。CloudWatchアラームは指定した期間にわたりメトリクスを監視し、指定した閾値に対するメトリクスの値に基づいて、指定したアクションを実行します。
アクションにはAmazon SNSによる通知や、EC2アクション（停止、終了、再起動など）、Auto Scaling、Systems Managerの機能実行（Run Commandなど）があります。

では、実際に画面の操作に移っていきましょう。

まず、Amazon CloudWatchのダッシュボードに遷移し、左メニュー`すべてのアラーム`を選択してください。
画面右上`アラームの作成`ボタンをクリックしてください。

![スクリーンショット 2023-08-18 22.19.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/1f07d59f-0428-0c86-45c0-342c11b6502f.png)

`メトリクスの選択`ボタンをクリックしてください。

![スクリーンショット 2023-08-18 22.20.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/f4ee60c7-f560-eb02-d9b6-c983a2acf6a8.png)

検索窓に`WA-Lab-DataReadFunction`と入力し、エンターキーを押下してください。
検索されたもののうち`Lambda > リソース別`リンクをクリックしてください。

![スクリーンショット 2023-08-18 22.22.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/44b91d62-89e6-09f1-7590-84e814b64b02.png)

利用可能なLambdaのメトリクスの一覧が表示されます。
メトリクス名`Invocations`をチェックし、右下`メトリクスの選択`ボタンをクリックしてください。

![スクリーンショット 2023-08-18 22.23.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/1c11923d-3c20-096d-0b1a-5f2a86ad8879.png)

`メトリクスと条件の指定`の入力を行います。

まず、`メトリクス`セクションの入力です。
`統計`を`合計`に変更してください。
`期間`を`1分`に変更してください。

![スクリーンショット 2023-08-18 22.26.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/ab0d1669-a9d2-682e-8090-c7d8af0dbada.png)

`条件`セクションの入力です。
`しきい値の種類`は`静的`を選択してください。
`Invocations が次の時...`は`より低い`を選択してください。
`... よりも`の部分は1分毎にLambda関数が呼び出される最小回数を入力します。つまり、`1`を入力してください。
`その他の設定`をクリックし、展開してください。
`アラームを実行するデータポイント`はメトリクスの`N`個のデータポイントのうち`M`個がしきい値を超えた場合に、アラーム状態に遷移するための設定です。
今回は`N`、`M`ともの`1`を設定します。つまり、`1 / 1`と入力してください。

https://dev.classmethod.jp/articles/suppress_false_alarms_alarm_to_ok_with_datapointstoalarm-suppress_false_alarms_alarm_to_ok_with_datapointstoalarm/#toc-2

`欠落データの処理`は`欠損データを不正(しきい値を超えている)として処理`を選択します。

![スクリーンショット 2023-08-19 10.14.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/517893f7-9dda-af4a-af0f-0b4484889f74.png)

入力が終わったら画面最下部の`次へ`ボタンをクリックしてください。

`アクションの設定`の入力を行います。

`通知`セクションの入力です。
`アラーム状態トリガー`は`アラーム状態`を選択してください。
`次の SNS トピックに通知を送信`は`既存の SNS トピックを選択`を選択してください。
`通知の送信先`の入力欄をクリックすると、入力候補のSNSトピック名が表示されます。`WA-Lab-Dependency-Notification`を入力してください。
`E メール (エンドポイント)`に表示されているメールアドレスがCloudFormationスタック作成時に入力したものと同一であることを確認してください。
入力が終わったら画面最下部の`次へ`ボタンをクリックしてください。

![スクリーンショット 2023-08-18 23.06.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/df0bd4b5-0f10-4cd8-59e7-0099ce3ab009.png)

`名前と説明を追加`の入力を行います。

`名前と説明`セクションの入力です。
`アラーム名`は今回`WA-Lab-Dependency-Alarm`とします。
入力が終わったら画面最下部の`次へ`ボタンをクリックしてください。

![スクリーンショット 2023-08-18 23.09.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/d6e6bb44-b2d0-4c51-1b9b-fae079ab5171.png)

`プレビューと作成`で入力内容を確認したら、画面最下部の`アラームの作成`ボタンをクリックしてください。

アラームが作成されるとCloudWatchの`すべてのアラーム`画面に戻ります。
一覧に先ほど作成したアラームが表示されています。
作成したばかりだとアラーム条件を判定するためのデータが足りないため`状態`の値が`データ不足`になっているのでデータが集まるまで数分待機します。

![スクリーンショット 2023-08-18 23.11.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/6f1a0f48-ccd5-ff92-a5db-adb5a9560a01.png)

データが収集されると`状態`が`OK`に変わります。
`名前`のアラーム名リンクをクリックしてください。

![スクリーンショット 2023-08-18 23.15.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/dd78d562-388e-e9ee-144d-c9d3522d85ba.png)

アラームの詳細画面に遷移します。
`グラフ`セクションでメトリクスが条件を満たしているかどうかを視覚的に確認することができます。
グラフの赤い線はしきい値を表し、それを下回ると`アラーム状態`になります。

![スクリーンショット 2023-08-18 23.20.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/6f796682-5ba1-f2c8-827e-cf21235ee5fd.png)

`履歴`タブを選択すると、アラームに関する状態の変更の履歴を確認することができます。

![スクリーンショット 2023-08-18 23.24.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/5d4ab28a-d208-2343-f621-ff68784350dc.png)

CloudWatchアラームでSNS通知が追加されたため、現在のアーキテクチャは以下のようになります。

![ArchitectureLast.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/c6443050-53f7-afd0-7e95-d2fdc60c47c4.png)

## TEST FAIL CONDITION

外部サービスに障害が発生し、S3バケットにデータが書き込まれなくなった場合、つまり、Lambda関数が呼ばれなくなった場合、通知を送信するアラームを作成しました。実際に通知されるか確認してみます。

外部サービスに障害を発生させる要因としては例えば以下があります。

- IAMロールが変更or削除され、外部サービスにS3バケットへの書き込み権限がなくなった
- S3バケットポリシーが変更され、外部サービスに書き込み権限がなくなった
- S3バケットの設定が変更され、S3イベント通知が削除されたため、Lambdaに通知が送信されなくなった
- 外部サービスにネットワーク関連の問題が発生し、S3バケットへ書き込みができなくなっている

今回は最後の例を再現します。
サブネットルートテーブルからデフォルトルートを削除し、EC2上で実行されている外部サービスがインターネットに到達できなくします。

では、実際に画面の操作に移っていきましょう。

まず、VPCのダッシュボードに遷移し、左メニュー`ルートテーブル`を選択してください。
ルートテーブル`WA-Lab-RouteTable`をチェックし、`ルート`タブを選択して、`ルートを編集`ボタンをクリックしてください。

![スクリーンショット 2023-08-19 9.41.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/64bae697-29a0-0891-fe7d-18bc3d4d1cb6.png)

`送信先`が`0.0.0.0/0`のルートを`削除`ボタンをクリックし、削除します。
そして、`変更を保存`ボタンをクリックしてください。

![スクリーンショット 2023-08-19 9.43.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/fd62ec09-6677-2000-6c55-b3e35ffff82d.png)

以上の操作により、EC2上で実行されている外部サービスはインターネットに到達できなくなったため、S3バケットにデータを書き込むことができなくなりました。
アラームの状態と通知が送信されるかを確認します。

Amazon CloudWatchのダッシュボードに遷移し、左メニュー`すべてのアラーム`を選択してください。
アラーム`WA-Lab-Dependency-Alarm`のリンクをクリックしてください。

![スクリーンショット 2023-08-19 9.50.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/d015e827-e290-ba89-de54-7933de23ab5a.png)

設定変更してから数分待つとアラームの状態が`OK`から`アラーム状態`に変更されます。

![スクリーンショット 2023-08-19 10.17.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/bb1bf8bd-6896-59cb-d9df-b31ddb75e2df.png)

`履歴`タブを選択すると、`状態の更新`イベントが発生し、`アクション`としてSNSの通知が送信されたことがわかります。

![スクリーンショット 2023-08-19 10.21.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/6f09807d-52b2-52e0-e158-f8a19a7ee75c.png)

同時にSNSトピックの購読者に通知メールが送信されます。
通知メールには状態変更の理由など詳細な情報が記載されています。

![screencapture-mail-google-mail-u-0-2023-08-19-10_19_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/c88da096-34df-2e57-2538-2901e6560ad4.png)

外部サービスが障害から復旧したことを再現するため、先ほどサブネットルートテーブルから削除したインターネットゲートウェイへのデフォルトルートを復活させましょう。
数分するとグラフのステータスが`アラーム状態`から`OK`に変更されます。

![スクリーンショット 2023-08-19 10.21.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/de69a23b-dedc-9727-9001-72f03492d200.png)

`履歴`タブを選択すると、`状態の更新`イベントが発生したことがわかります。

![スクリーンショット 2023-08-19 10.21.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/f56c99b6-af3b-85af-7858-4553f6923fab.png)

## BONUS CONTENT

CloudWatchメトリクスとCloudWatchアラームによって依存関係となっている外部サービスのモニタリングをすることができました。
通知により、関係者に問題を警告することはできるようになりましたが、このようなイベントを追跡することで問題解決をより確実なものにすることができます。
これはSystems Manager OpsCenterを活用することで実現できます。
OpsCenterは運用上の課題、問題をOpsItemという単位で管理し、追跡し、現在のステータスを迅速に把握することができます。

CloudWatchアラームで、通知と同時にOpsItemを自動作成するように設定してみます。OpsItemはLambda関数で作成します。
設定後のアーキテクチャは以下になります。

![ArchitectureBonus.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/a24660d5-a5e9-a23a-d99c-a9beb15de651.png)

では、実際に画面の操作に移っていきましょう。

まず、Amazon SNSのダッシュボードに遷移し、左メニュー`トピック`を選択してください。
トピック`WA-Lab-Dependency-Notification`リンクをクリックしてください。

![スクリーンショット 2023-08-19 10.40.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/f6f66766-60ea-beb4-d481-cf96756083df.png)

`サブスクリプション`タブを選択し、`サブスクリプションの作成`ボタンをクリックしてください。

![スクリーンショット 2023-08-19 10.41.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/764d31fa-e56e-9b28-dd2b-74a9a4c6cbee.png)

`詳細`セクションの入力です。
`トピックARN`はデフォルト値で構いません。
`プロトコル`は`AWS Lambda`を選択してください。
`エンドポイント`はCloudFormationスタックの出力に表示されているキー`OpsItemFunction`の値を指定してください。
入力し終えたら、画面最下部の`サブスクリプションの作成`ボタンをクリックしてください。

![スクリーンショット 2023-08-19 10.46.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/760f98d6-b922-aca0-893e-1be4eede9477.png)

Lambdaが自動実行されるか確認するためにCloudWatchアラームの状態を`アラート状態`にします。前章で実施したようにサブネットルートテーブルからインターネットゲートウェイへのデフォルトルートを削除してください。
数分すると通知メールが送信されるのと同時にSystems Manager OpsCenterにOpsItemが作成されます。
作成された`ID`リンクをクリックしてください。

![スクリーンショット 2023-08-19 10.55.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/f8a7fbed-35f2-ff20-7ee8-1fc7b57a6b99.png)

OpsItemの詳細画面に遷移します。
`OpsItemの詳細`をクリックすると`タイトル`、`重要度`、`ステータス`など確認ができます。
`関連リソース`セクションでは、問題に関連するAWSリソースを確認することができます。
`ランブック`セクションでは、作成済みのRunbookを実行し、修復を自動化することができます。

![screencapture-ap-northeast-1-console-aws-amazon-systems-manager-opsitems-oi-2e6fcdc1812c-workbench-2023-08-19-10_58_44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545707/680c6929-51e0-ecb9-762b-7bba9f36afc9.png)

## TEAR DOWN THIS LAB

削除するリソースの箇条書き

1. CloudWatchアラーム
2. Systems Manager OpsCenterのOpsItem
3. CloudFormationスタック
4. S3バケット（`cf-templates-`から始まるバケット）
5. SNSサブスクリプション

詳細は以下を参照ください。

https://www.wellarchitectedlabs.com/operational-excellence/100_labs/100_dependency_monitoring/6_cleanup/