AWS EC2において空きメモリ容量をCloudWatchに蓄積し、しきい値を下回った際にAWS SNS Lambda経由でChatworkにアラートを飛ばす。

# 対象
- AWS EC2インスタンスをご利用中でOSがWindows Server 2016, Windows Server 2003-2012 Rである。
- コミュニケーションツールとして、Chatworkを使用している。
- 空きメモリ容量やディスク容量などをチェックする際に、EC2インスタンスにRDP接続して確認することを面倒と感じている。または危険だと感じている。
- **値が危険域に達しそう、した際にコミュニケーションツールなどすぐに気づける形で通知が来てほしいと感じている。**
    - CloudWatchのアラーム機能では、直接AWS Lambda関数を呼び出せないため、中継としてAWS SNSを使用する。

# Chatwork API利用申請

[チャットワークAPIドキュメント](http://developer.chatwork.com/ja/) の下部「APIの利用申請」より行う。

# EC2インスタンスにSSMエージェントをインストール
すでに導入済みの場合は対応不要。
AWSのドキュメントを参考に実施する。
[Windows インスタンスで SSM エージェント をインストールし設定する - Amazon EC2 Systems Manager](http://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/sysman-install-ssm-win.html)

# AWS CloudWatchに空きメモリ容量を蓄積する

以下を参考に実施する。
[AWS CloudWatch で、Amazon EC2 Windows インスタンスのパフォーマンスとログの監視をしてみる - Qiita](https://qiita.com/kusokamayarou/items/261efb81d91137ae8321)

# AWS Lambda関数の作成

- [Lambda Management Console](https://console.aws.amazon.com/lambda/) を開く。
- 「関数の作成」をクリックする。
- 以下のように入力する。
    - 状況に応じて設定内容は適宜変更する。

| 項目 | 入力/選択内容 |
|:-----------------|:------------------|
|名前*|sns_to_chatwork|
|ランタイム*|python 2.7|
|ロール*|テンプレートから新しいロールを作成|
|ロール名*|lambda_basic_execution|

- 関数コードを入力する。

```python:
#!/usr/bin/env python
# -*- coding: utf-8-unix; -*-
"""AWS Lambda Function - post AWS CloudWatch alert to chatwork
"""
from __future__ import print_function

import sys
import json
import urllib
import urllib2

ROOM_ID = "12345678"            # alert room
TOKEN = "abcd1234abcd1234abcd1234abcd1234" # API token

def post_chatwork(subject, message):
    body = "[info][title]{}[/title]{}[/info]".format(
        subject, message)

    req = urllib2.Request(
        "https://api.chatwork.com/v2/rooms/{}/messages".format(ROOM_ID),
        urllib.urlencode({"body": body}),
        {"X-ChatWorkToken": TOKEN})

    res = urllib2.urlopen(req)
    page = res.read()
    res.close()

def lambda_handler(event, context):
    data = json.loads(event["Records"][0]["Sns"]["Message"])

    subject = data["AlarmName"]
    message = json.dumps(data, indent=4,ensure_ascii=False)

    post_chatwork(subject, message)

    return "OK"
```

# AWS SNSトピックの作成

- [AWS SNS](https://ap-northeast-1.console.aws.amazon.com/sns/) を開く。
- 「新しいトピックの作成」をクリックする。
- 以下のように入力する。
    - 状況に応じて設定内容は適宜変更する。

| 項目 | 入力/選択内容 |
|:-----------------|:------------------|
|トピック名|alert_hoge|
|表示名|alert_hoge|
- 作成したトピックを選択し、「アクション」から「トピックへのサブスクリプション」をクリックする。
- 以下のように入力する。
    - 状況に応じて設定内容は適宜変更する。

| 項目 | 入力/選択内容 |
|:-----------------|:------------------|
|トピック ARN|{そのまま}|
|プロトコル|AWS Lambda|
|エンドポイント|arn:aws:lambda:ap-northeast-1:123456781234:function:sns_to_chatwork|
|バージョンまたはエイリアス|defalt|
- 「サブスクリプションの作成」をクリックする。

# AWS CloudWatchにアラームを追加する

- [CloudWatch Management Console](https://ap-northeast-1.console.aws.amazon.com/cloudwatch/) を開く。
- 左の「アラーム」をクリックする。
- 「アラームの作成」をクリックする。
- アラームの対象のメトリクスを選択し、「次へ」をクリックする。
- 以下のように入力する。
    - アラームのしきい値

| 項目 | 入力/選択内容 |
|:-----------------|:------------------|
|名前|{任意の文字列}|
|説明|{任意の文字列}|
|次の時:Available-Memory が:(不等号)|{任意の不等号}|
|次の時:Available-Memory が:(しきい値)|{任意の数値}|
|次の時:Available-Memory を:|{任意の回数}|

- 以下のように入力する。
    - 追加設定

| 項目 | 入力/選択内容 |
|:-----------------|:------------------|
|欠落データの処理方法:|見つかりません|

24時間起動しっぱなしの本運用サーバーでは上記設定が望ましい。

- 以下のように入力する。
    - アクション

| 項目 | 入力/選択内容 |
|:-----------------|:------------------|
|アラームが次の時:|状態: 警告|
|通知の送信先:|alert_hoge|

- 「アラームの作成」をクリックする。

- メモリ空き容量がしきい値を下回ると、以下のようなアラートが出力される。
![lambdaよりchatwork投稿.PNG](https://qiita-image-store.s3.amazonaws.com/0/218550/ceb5091a-3496-e64f-2a18-b9a6c52804ae.png)
出力形式は、お好みに応じてlambda関数を編集して変更する。