【AWS_37】CloudWatchでApache httpdサービスを監視してアラートをメール送信する

CloudWatchの勉強のため、下記記事を参考にCloudWatchエージェントを使用してApache WebサーバーのHTTPサービスを監視し、HTTPサービスが停止した際にメール通知アラートが送信されるよう設定してみます。
CloudWatchエージェントは、Apacheのログやシステムメトリクスを収集し、監視やアラートに活用できるそうです。
実際の運用でCloudWatchエージェントがどれくらい登場するのかはわかっておりませんが、同様の記事が多数ありましたのでそれなりに利用されているのかなと思いました。
CloudWatchでApache httpdサービスを監視し、停止時にメール通知アラートを発生させる方法
https://qiita.com/free-honda/items/d7eb9e39cfc95ac6e91b
目次
構成図

事前準備
VPC関連、EC2、Apacheはインストール、設定済みで「http://パブリックIPアドレス」へアクセスしてWEBページが表示されることを確認しておきます。今回は、簡易なindex.htmlを作成してアップしました。
EC2インスタンスには、SSHではなくセッションマネージャーで接続しています。

EC2インスタンスに必要なIAMロールの追加
IAMロールの作成
CloudWatchエージェントを正しく機能させるためには、EC2インスタンスに以下のIAMロールを追加する必要があります。
このロールは、CloudWatchへのメトリクスデータの送信や取得を許可します。
・cloudwatch:PutMetricData(メトリクスを作成するために必要です。)
・cloudwatch:GetMetricStatistics(CloudWatch コンソールの他の部分やダッシュボードウィジェットにあるグラフを見るのに必要です。)
・cloudwatch:ListMetrics(CloudWatch コンソール内または CLI のメトリクス名を表示または検索するのに必要です。)
■参考:
AWS管理ポリシーの「CloudWatchAgentServerPolicy」を選択しても同様にメトリクスは取得できました。(※以下画像参照)
ただ、他にもいろいろと情報が取得されるので検証のためだけであれば参考サイトに提示いただいている権限だけのほうがわかりやすいと思いました。

Amazon CloudWatch の許可リファレンス
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/permissions-reference-cw.html
AWSマネジメントコンソールで「IAM」を検索します。
左ペインのロールをクリックし、画面右上の「ロールを作成」をクリックします。
信頼されたエンティティを選択画面で「AWSのサービス」を選択、ユースケースで「EC2」を選択し、「次へ」をクリックします。


許可を追加画面では何も選択せずに「次へ」をクリックします。
名前、確認、および作成画面でロール名を入力、その他はデフォルトのままとし、「ロールを作成」をクリックします。
ロール名:任意の名前



ロールが作成されました。

IAMロールへインラインポリシーを追加
IAMロールを作成しただけでポリシーや権限など何も許可されていないので追加します。今回は先に記載したとおり3つの権限を追加します。
作成したロールをクリックします。
「許可」タブ > 「許可を追加」 > 「インラインポリシーを作成」をクリックします。

ポリシーエディタのJSONタブを選択し、以下のように記述して「次へ」をクリックします。(私の場合、もともと記載されていたものを上書きしました)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudwatch:PutMetricData",
"cloudwatch:GetMetricStatistics",
"cloudwatch:ListMetrics"
],
"Resource": "*"
}
]
}

ポリシー名を入力し、「ポリシーの作成」をクリックします。

「許可」タブを見るとインラインポリシーが追加されました。

IAMロールをEC2インスタンスにアタッチ
作成したIAMロールをEC2インスタンスにアタッチします。
AWSマネジメントコンソールで「EC2」を検索します。
左ペインのインスタンスをクリック、IAMロールを割り当てたいEC2インスタンスにチェックを入れて、アクション > セキュリティ > IAMロールを変更 をクリックします。

IAMロールを変更画面のプルダウンより、先ほど作成したIAMロールを選択し、「IAMロールの更新」をクリックします。

画面下の「セキュリティ」タブをクリック、「IAMロール」へIAMロールが割り当てられていることを確認します。

CloudWatchエージェントのインストール
EC2インスタンスにログインして以下コマンドを実行し、CloudWatchエージェントをインストールします。Complete!が表示されれば成功です。
sudo dnf -y install amazon-cloudwatch-agent

CloudWatchエージェントを起動する前に状態を確認しておきます。Statusがstoppedで停止していることがわかります。
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status
-m :収集するメトリクスとログのモードを指定します。
-a :特定のアクションを実行します。

次に、CloudWatchエージェントを起動します。
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a start

あらためてCloudWatchエージェントの状態を確認します。Statusがrunningに変わり、起動していることが確認できました。
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status

CloudWatchエージェントの設定ファイルを作成
ApacheのHTTPのプロセスを監視するためにCloudWatchエージェントの設定ファイルを作成します。
他の記事を見るとウィザードで作成する方法もあるようですが、参考にさせていただいた記事どおり手動で設定ファイルを作成する手順で進めたいと思います。
cd /opt/aws/amazon-cloudwatch-agent/etc/
sudo vi amazon-cloudwatch-agent.json
amazon-cloudwatch-agent.jsonに以下を入力し、保存します。
{
"metrics": {
"metrics_collected": {
"procstat": [
{
"exe": "httpd",
"measurement": [
"pid_count"
],
"metrics_collection_interval": 60
}
]
}
}
}

この設定では、Apache(httpd)のプロセスが正しく動作しているかを確認し、TCP 80ポート(HTTP)がリッスンしているかを監視するそうです。
現時点では、私はjsonの書き方も理解できてませんのでいったんは参考サイトを参照させていただいたままとなります。
設定ファイルを変更したら、CloudWatchエージェントを再起動して新しい設定を反映させます。
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a stop
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a start
systemctlコマンドでも対応しています。
sudo systemctl restart amazon-cloudwatch-agent
■参考
CloudWatchエージェントは、systemctlコマンドでも操作できます。
systemctl で起動した場合は、設定ファイルパス /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json の設定を読み込もうとするそうなので起動コマンドによって設定ファイルの場所を意識しておく必要があります。
上記で作成した設定ファイルを読み込ませます。これで完了です。
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json -s
-c :設定ファイルのパスを指定します。
-a fetch-config によりエージェントは最新バージョンの CloudWatch エージェント設定ファイルをロードします。
-s がエージェントを開始します。

CloudWatchの確認
AWSマネジメントコンソールで「cloudwatch」を検索します。
左ペインのすべてのメトリクス > 参照タブをクリックすると画面に「CWAgent」が追加されていることが確認できました。

CWAgentをクリック > exe,host,pid_finderをクリックするとさらに詳細な情報が確認できました。

表示されている情報の中から今回の対象のインスタンスIDにチェックを入れます。
グラフなどが表示されることが確認できました。(※グラフが表示されるまでしばらく時間がかかります)
「グラフ化したメトリクス(1個)」タブへ移動し、以下赤枠の箇所を「1秒」へ変更するとグラフがすぐに表示されると思います。
あと触っていた時に感じたことは「参照」タブへ戻っておかないと時間をあけてCloudWatch > すべてのメトリクスとクリックしていくといきなり「グラフ化したメトリクス」タブへ画面が遷移し、それより上の階層画面に行く方法がわからなくなって混乱します。
CloudWatchのすべてのメトリクスを閉じる時は、「参照」タブへ戻っておいたほうがよいなと感じました。

CloudWatchアラームの作成
CloudWatchエージェントでApacheのプロセスやポート監視を設定したので、次に、HTTPサービスが応答しない場合のアラームを設定します。
AWSマネジメントコンソールで「cloudwatch」を検索します。
左ペインのアラームの状態 > アラームの作成をクリックします。
メトリクスの選択をクリックします。

CWAgentをクリックします。

exe,host,pid_finderをクリックします。

httpdにチェックを入れて、「メトリクスの選択」をクリックします。

メトリクスと条件の指定画面で条件項目を以下のとおり選択、入力し、次へをクリックします。
procstat_lookup_pid_countの値が「0」になるとメールが送信されるよう設定しています。
しきい値の種類:静的
procstat_lookup_pid_count が次の時…:以下
…よりも:0


アラームが発生した際に通知を受け取るためのSNSトピックを選択します。SNSトピックが未作成の場合は、新しく作成します。
ここでは、私のGmailのアドレスに通知を送るように設定しています。
「通知」の内容を入力後に「トピックの作成」をクリックします。

「トピックの作成」をクリックすると設定したメールアドレスにメールが送信されます。
件名が「AWS Notification – Subscription Confirmation」というメールが受信されます。
受信したメール本文にある「Confirm subscription」をクリックします。
すると以下のAWSの画面に遷移します。
※ここまでやっておかないとcloudwatchでアラームの設定した時にサブスクリプションに関するアラートが出ます

ここまで確認できたら「次へ」をクリックします。

任意のアラームの名前を設定して「次へ」をクリックします。今回は「Apache HTTPS Service Down Alert」と設定しました。

「プレビューと作成」画面で設定内容を確認し、「アラームの作成」をクリックします。


アラームが作成されました。
私の場合、「アラームについてさらに読む」をクリックして、ブラウザで元の画面に戻ったら作成したアラームが表示されました。

先ほど受信したSNSに関するメールでサブスクリプションに対する確認をしてなかったので以下のアラートが出ました。(青色部分)
受信したメール本文にある「Confirm subscription」をクリックすることで確認が完了します。
それ以外では「状態」が「OK」であることを確認しておきます。

AWSマネジメントコンソールで「sns」を検索し、「Simple Notification Service」をクリックします。
左ペインのサブスクリプションをクリックします。
エンドポイントに先ほど登録したメールアドレスが表示されており、ステータスが「確認済み」となっていることを確認します。
サブスクリプションも利用可能な状態であることが確認できました。

これで、ApacheのHTTPSサービスが停止した際にアラートが発生する設定が完了しました。
検証結果の確認
httpdサービスを停止
ここまでの設定が完了したので、以下のコマンドでEC2インスタンスの「httpd」サービスを停止します。
停止前にhttpdプロセスの状態を確認しておきます。
ps -ef | grep httpd

EC2インスタンスの「httpd」サービスを停止します。
sudo systemctl stop httpd

httpdプロセスがないことを確認します。
ps -ef | grep httpd

CloudWatchで確認
AWSマネジメントコンソールで「cloudwatch」を検索します。
左ペインすべてのアラーム > 作成したアラーム名(今回であればApache HTTPS Service Down Alert)をクリックします。
グラフの画面でhttpdサービス停止後からCloudWatchのサービス画面からグラフが変化していることが確認できます。

グラフがどんどん下降していき、「0」にむかっていきます。「0」になっても右上の表示が「OK」で黄緑のバーの状態であればまだメールは送信されません。赤色のバーになった時に「OK」から「アラーム状態」と表示が変わり、メールが送信されました。

設定したメールアドレス宛てに以下のメールを受信しました。

以上で検証は完了となります。
CloudWatchでApache httpdサービスを監視してアラートをメール送信することができました。
リソースの削除
簡単にですが、作成したリソースの削除について記載します。(CloudWatchのメトリクスであるCWAgentは、仕様により削除できません)
CloudWatch:
・すべてのアラームから作成したアラームを削除
・すべてのメトリクスのCWAgentは削除できません
AWSのよくある質問より
https://aws.amazon.com/jp/cloudwatch/faqs/#monitoring

IAMロール
・EC2インスタンスからデタッチ
・IAMロールの削除
SNS
・サブスクリプションを削除
・トピックを削除
EC2インスタンスの削除
VPCの削除
まとめ
CloudWatchでApache httpdサービスを監視してアラートをメール送信することができました。次は、CloudWatchでApache httpdサービスのログを収集する検証をしてみたいと思います。
以下、他の記事をまとめた一覧です。AWSもまとめています。