クラウド運用の強化：CloudWatchの「HealthyHostCount」とEventBridgeを使ったEC2障害検知システムの作り方

## はじめに
AWSインフラストラクチャを運用する上で、EC2インスタンスの状態を継続的に監視することは非常に重要です。

特に、ターゲットグループ内に複数のEC2インスタンスが存在する場合、すべてのインスタンスが正常に動作していることを確認する必要があります。

本記事では、ターゲットグループ内の2台のEC2インスタンスでApacheサービスが停止したことを検知し、EventBridgeをトリガーする方法について解説します。

## 知識整理
ターゲットグループ内のEC2インスタンスの状態を監視するためには、以下のAWSサービスを活用します。

:::note
**CloudWatch アラーム:** 
EC2インスタンスのヘルス状態を監視し、特定のメトリクスが閾値を下回った際にアラームを発報します。**具体的には、ALB (Application Load Balancer) のターゲットグループに関連するメトリクスである HealthyHostCountを使用します。**

**EventBridge:** 
CloudWatchアラームの状態変更を監視し、アラームが発火したときに自動でアクションを実行できるようにするサービスです。
:::

検証の詳細については、以下の記事も参考にしてください。

https://dev.classmethod.jp/articles/elb-healthcheck-monitoring-by-cloudwatch-alarm/

## 実装手順
以下の手順で、ターゲットグループ内の2台のEC2インスタンスが停止したことを検知する設定を行います。

:::note warn
この記事は、ALBを用いて複数EC2インスタンスを負荷分散する手順に関する以前の記事の続きです。
:::

https://qiita.com/free-honda/items/d8fbcd649a711e8f283a

すでに2台構成のEC2インスタンスおよびALBの設定が完了していることを前提に進めていきます。

### 1. CloudWatch アラームの作成
AWSマネジメントコンソールにログインし、CloudWatchサービスを選択します。「アラーム」をクリックし、「アラームの作成」を選択します。

![スクリーンショット 2024-10-26 15.39.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/8cdee4a8-2a74-3e8d-0592-9c883f53d037.png)

「メトリクスの選択」画面で「``HealthyHostCount``」でフィルターし、該当のメトリクスを選択します。

![スクリーンショット 2024-10-26 15.40.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/b781a2ff-d53a-f522-9307-aa22d5702b31.png)

以下の折れ線グラフに示されるように、「``HealthyHostCount``」メトリクスの値が正しく取得できていることを確認します。

![スクリーンショット 2024-10-26 15.41.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/bea0ce39-cd7f-839e-f1c6-d813be14e101.png)

メトリクス名が「``HealthyHostCount``」であることを確認し、ここでは``HealthyHostCount`` が ``0`` またはそれ以下の場合にアラートが発報されるよう設定します。

![スクリーンショット 2024-10-26 15.45.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/d82a3730-a95c-b6f4-0ec5-c6f3385c9642.png)

アクションの設定画面では、特に設定せずに進めます。アラームが作成され、正常にデータが取得されていることが確認できました。

![スクリーンショット 2024-10-26 15.50.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/ec1c6d26-d01a-660b-fa7e-58ba3dbd4d25.png)

私の環境では以下のように設定していますが、ご自身の環境に合わせて適宜調整してください。

![スクリーンショット 2024-10-26 15.53.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/372c2b06-999d-5206-2a38-70b0c0238af7.png)

### 2. EventBridge ルールの作成
AWSマネジメントコンソールでEventBridgeサービスを選択し、「ルール」から「ルールの作成」をクリックします。

![スクリーンショット 2024-10-26 15.56.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/df86ca8a-a632-1484-58d4-83ef59a74515.png)

**障害パターンの場合**
以下のJSONを使用して、アラームが「OK」から「ALARM」に変わった際にトリガーされるルールを作成します。

```json
{
  "source": [
    "aws.cloudwatch"
  ],
  "detail-type": [
    "CloudWatch Alarm State Change"
  ],
  "detail": {
    "alarmName": [
      "HealthyHostCount"
    ],
    "previousState": {
      "value": [
        "OK"
      ]
    },
    "state": {
      "value": [
        "ALARM"
      ]
    }
  }
}
```

**通常パターンの場合**
次に、アラームが「ALARM」から「OK」に変わった際にトリガーされるルールを作成します。

```json
{
  "source": [
    "aws.cloudwatch"
  ],
  "detail-type": [
    "CloudWatch Alarm State Change"
  ],
  "detail": {
    "alarmName": [
      "HealthyHostCount"
    ],
    "previousState": {
      "value": [
        "ALARM"
      ]
    },
    "state": {
      "value": [
        "OK"
      ]
    }
  }
}
```

続けて、トリガー先を設定する項目が表示されますが、ここでは仮にLambda関数を指定します。

次回の記事では、Lambda関数を用いてALBの優先度を変更する技術検証を行います。

![スクリーンショット 2024-10-26 16.04.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/ce8c568e-de3d-03bb-b465-b9f0db3efca0.png)

最後に、EventBridgeのルールが2つ作成され、以下のようなステータス画面になります。ステータスが「``有効``」になっていることを確認してください。

![スクリーンショット 2024-10-26 16.09.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/a62ed19d-759b-da9d-510e-26b8471b5b80.png)


## 検証確認
### 障害発生時：``httpd``のサービス停止
設定が完了したら、ターゲットグループ内のEC2インスタンスで``httpd``サービスを停止し、CloudWatchアラームが正しく発火するか確認します。

以下のように``sudo systemctl stop httpd.service``コマンドで明示的に``httpd``のサービスを停止します。

```bash
[ec2-user@ip-10-0-7-185 ~]$ sudo systemctl stop httpd.service
[ec2-user@ip-10-0-7-185 ~]$ sudo systemctl status httpd.service
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since Sun 2024-10-27 01:07:57 UTC; 8s ago
     Docs: man:httpd.service(8)
  Process: 2964 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=0/SUCCESS)
 Main PID: 2964 (code=exited, status=0/SUCCESS)
   Status: "Total requests: 30; Idle/Busy workers 100/0;Requests/sec: 0.0733; Bytes served/sec:  53 B/sec"

Oct 27 01:00:59 ip-10-0-7-185.ap-northeast-1.compute.internal systemd[1]: Starting The Apache HTTP Server...
Oct 27 01:00:59 ip-10-0-7-185.ap-northeast-1.compute.internal systemd[1]: Started The Apache HTTP Server.
Oct 27 01:07:56 ip-10-0-7-185.ap-northeast-1.compute.internal systemd[1]: Stopping The Apache HTTP Server...
Oct 27 01:07:57 ip-10-0-7-185.ap-northeast-1.compute.internal systemd[1]: Stopped The Apache HTTP Server.
[ec2-user@ip-10-0-7-185 ~]$ 
```

:::note warn
ここでは、作成した2台のインスタンスでApacheのサービス停止を行います。
:::

以下のように「502 Bad Gateway」が表示されていれば、2台とも``httpd``サービスが正常に停止しています。

![スクリーンショット 2024-10-27 10.21.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/2da05ec0-4b64-2743-86a0-d3519e75f705.png)

#### 障害発生時：CloudWatchアラーム側の確認

「``HealthlyHostCount``」アラームがアラート状態になっていることを以下のように確認できます。

![スクリーンショット 2024-10-27 10.23.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/5f19154e-2874-4fb7-8b53-6bf4b7a808ea.png)

この状態は、ALBのターゲットグループに登録された2台のEC2インスタンスのヘルスチェックが両方失敗し、「``0``」になっていることを示します。

![スクリーンショット 2024-10-27 10.26.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/6bce25f8-e941-84ca-7d2f-68473d212e67.png)

#### 障害発生時：EventBridgeルール側の確認

アラームが発火すると、設定したEventBridgeルールがトリガーされ、アクションが正しく実行されるかを確認します。

「``HealthlyHostCount``」アラームがOKからALARMに変わった際に、設定したルールが実行されていることを確認します。

![スクリーンショット 2024-10-27 10.36.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/8ab38afe-3e81-37a2-a423-b2e6208de1e1.png)

:::note warn
EC2インスタンスのApacheサービスを停止したタイミングで、事前に作成した障害発生用のイベントルールがトリガーされていることが確認できました。
:::

### 障害復旧時：``httpd``のサービス起動

次に、障害復旧時のパターンとして、ALBに紐づくターゲットグループのヘルスチェックが正常に戻った場合の動作確認を行います。

つまり、「``HealthlyHostCount``」アラームがALARMからOKに変わった際に、設定したルールが動作するかを検証します。

以下のように``sudo systemctl start httpd.service``コマンドで明示的に``httpd``のサービスを起動します。

```bash
[ec2-user@ip-10-0-19-42 ~]$ sudo systemctl start httpd.service
[ec2-user@ip-10-0-19-42 ~]$ systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2024-10-27 01:36:53 UTC; 2s ago
     Docs: man:httpd.service(8)
 Main PID: 3769 (httpd)
   Status: "Processing requests..."
   CGroup: /system.slice/httpd.service
           ├─3769 /usr/sbin/httpd -DFOREGROUND
           ├─3770 /usr/sbin/httpd -DFOREGROUND
           ├─3771 /usr/sbin/httpd -DFOREGROUND
           ├─3772 /usr/sbin/httpd -DFOREGROUND
           ├─3773 /usr/sbin/httpd -DFOREGROUND
           └─3774 /usr/sbin/httpd -DFOREGROUND

Oct 27 01:36:53 ip-10-0-19-42.ap-northeast-1.compute.internal systemd[1]: Starting The Apache HTTP Server...
Oct 27 01:36:53 ip-10-0-19-42.ap-northeast-1.compute.internal systemd[1]: Started The Apache HTTP Server.
[ec2-user@ip-10-0-19-42 ~]$ 
```

:::note warn
ここでは、作成した2台のインスタンスでApacheサービス起動を行います。
:::

以下のように作成したHTMLページが表示されていれば、2台とも``httpd``サービスが正常に起動しています。

![スクリーンショット 2024-10-27 10.50.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/c7026b76-8d78-b868-0502-39e6a9e77991.png)

#### 障害復旧時：CloudWatchアラーム側の確認
「``HealthlyHostCount``」アラームがOK状態になっていることが以下のように確認できます。

![スクリーンショット 2024-10-27 10.51.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/efe4aca5-7692-6f44-1741-3a96815bef92.png)

この状態は、ALBのターゲットグループに登録されている2台のEC2インスタンスのヘルスチェックが正常に成功し、「``2``」に戻っていることを示します。

![スクリーンショット 2024-10-27 10.52.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/d4896efd-b997-4f37-688d-e7978fb5b41e.png)

CloudWatchアラームの履歴タブでも、``アラーム``状態から``OK``に変わったことが確認できます。

![スクリーンショット 2024-10-27 10.54.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/db25dff4-ad14-659f-a826-7f53dd79dac6.png)

#### 障害復旧時：EventBridgeルール側の確認
アラームがOK状態になった場合、EventBridgeルールがトリガーされ、設定したアクションが正しく実行されるかを検証します。

「``HealthlyHostCount``」アラームが ``アラーム状態`` から ``OK`` に変わった際に、設定したルールが実行されていることが確認できます。

![スクリーンショット 2024-10-27 10.56.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/dadcefe7-f3f7-2a40-0f51-1adf8ad7e07b.png)

:::note warn
EC2インスタンスのApacheサービスを起動し、ヘルスチェックが正常に戻ったタイミングで、事前に作成した障害復旧用のイベントルールがトリガーされて動作していることが確認できました。
:::

## まとめ
ターゲットグループ内の2台のEC2インスタンスのApacheサービスの停止を検知するには、CloudWatchアラームとEventBridgeを組み合わせる方法が一般的です。

これにより、システムのヘルスチェックが自動化され、異常を早期に検知することが可能となります。

AWSを活用したインフラの監視と自動化は、効率的な運用に欠かせない重要な要素であり、慣れるまでは難しく感じるかもしれませんが、学ぶ価値が十分にあります。

本記事が、技術の支えとなることを願っています！

## 参考文献

https://dev.classmethod.jp/articles/elb-healthcheck-monitoring-by-cloudwatch-alarm/