CloudWatchアラーム通知をSlackにする

[CloudWatch カスタムメトリクスを色々監視する](https://qiita.com/hf7777hi/items/cd1f146895d487f3b60a)
にてカスタムメトリクスを導入しました。

これでアラートを設定すると登録したメールアドレスに対して通知が来ます。
これでは、見落としがちなので、今回はSlackに通知するようにしたいと思います。

CloudWatch → Lambda → Slack
の流れでSlackに通知します。
CloudWatchのアラートをLambdaで受けてSlackに流す形です。

#アラーム設定
まずはアラームを設定します。
####監視したいメトリクスにチェックを入れる
![スクリーンショット 2018-03-24 14.29.32.png](https://qiita-image-store.s3.amazonaws.com/0/86605/1899bc48-1b69-cb46-7fdf-d9a755363738.png)
####グラフ化したメトリクスタブを開く
ベールマークをクリックする。
![スクリーンショット 2018-03-24 14.31.06.png](https://qiita-image-store.s3.amazonaws.com/0/86605/d3991931-2906-6323-883c-c4f83ee69fa1.png)
####アラーム登録
![スクリーンショット 2018-03-24 14.35.52.png](https://qiita-image-store.s3.amazonaws.com/0/86605/11ef25f0-cfd1-2f61-7a66-58712b60839d.png)

通知メールは受信可能なメールアドレスを登録します。

通知は、状態が切り替わった時に一回だけされます。
そのため、OKと警告の通知はセットで登録しておくことをおすすめします（+不足も登録しておいてもいいです）。不足状態は、アラーム設定対象のメトリクスが計測不可能な状態になった時になります。

例）
OK→警告　警告の通知が来ます。
警告→OK　OKの通知が来ます。

これで、設定したメールアドレスに対してアラートの通知が来ます。


#Slackの準備
https://slack.com/apps
から、「Incoming WebHooks」を「Add Configuration」を押して、追加します。
![スクリーンショット 2018-03-24 14.50.25.png](https://qiita-image-store.s3.amazonaws.com/0/86605/800bc79b-4b71-3d80-da71-76506f5d4e19.png)

通知するチャンネルを選択します（cloudwatchチャンネルを選択しました）。
![スクリーンショット 2018-03-24 14.52.48.png](https://qiita-image-store.s3.amazonaws.com/0/86605/3f2ef646-7dd8-3948-e2d7-6bfba7b4ec31.png)

登録すると、以下の「Webhook URL」が発行されるので記憶しておく。
![スクリーンショット 2018-03-24 14.54.06.png](https://qiita-image-store.s3.amazonaws.com/0/86605/83b2bf6a-ed72-c336-1f84-9fb63acbc618.png)


#Lambdaの設定
一応料金確認。まあアラームだけでそんなにいかないので無料枠で全然いけます。
https://aws.amazon.com/jp/lambda/pricing/
> 無料利用枠
> 1,000,000 件のリクエスト
> USD/月
> 400 GB-秒
> 1 か月あたりのコンピューティング時間.
> 
> Lambda の無料利用枠は、12 か月間の AWS 無料利用枠の期間が終了しても自動的に期限切れになることはありません。既存および新規の AWS のお客様は、無期限にご利用いただけます。

###IAMのKMSで暗号キーでWebhookURLを暗号化
**※無料枠で使いたい方はここをすっ飛ばして「関数作成」に移ってください。以下の感じで料金がかかります。**
[Lambdaのcloudwatch-alarm-to-slackで無料と思ってKMS暗号化キーを使ったら2円かかったので関数修正した](https://qiita.com/hf7777hi/items/6226a17ddfc17ad9268c)

IAM > 暗号化キー > キーの作成　から暗号化キーを作成します。

名前は「cloudwatch-alarm-to-slack」にしました。
![スクリーンショット 2018-03-24 15.13.14.png](https://qiita-image-store.s3.amazonaws.com/0/86605/8b8c3185-898c-791c-1cdc-d6dca43fdccc.png)
タグ名は適当に。
![スクリーンショット 2018-03-24 15.13.40.png](https://qiita-image-store.s3.amazonaws.com/0/86605/9d91f8fd-439c-a227-cacc-c83d85543739.png)
キーの管理および使用許可を設定します。今回はどっちも「admin」にしました。
![スクリーンショット 2018-03-24 15.13.57.png](https://qiita-image-store.s3.amazonaws.com/0/86605/f2cab0f8-df28-fc64-d4f8-ba627dcfa384.png)
![スクリーンショット 2018-03-24 15.14.09.png](https://qiita-image-store.s3.amazonaws.com/0/86605/db609714-cd4e-c738-143d-184fa0653995.png)
以下のようにできました。
![スクリーンショット 2018-03-24 15.14.33.png](https://qiita-image-store.s3.amazonaws.com/0/86605/71d57aa0-db35-f718-2c1a-1974c6965c8c.png)


EC2へログインし、以下コマンドを実行します(aws configureしていない場合はしてください)。

```
$ aws kms encrypt --key-id alias/cloudwatch-alarm-to-slack --plaintext "hooks.slack.com/services/************************"
```
うまくいくと以下のように暗号化されたWebhookURLが取得できます。
「CiphertextBlob」がそうです。

```
{
    "KeyId": "arn:aws:kms:ap-northeast-1:395:key/**************", 
    "CiphertextBlob": "*********************************"
}
```

※以下のようにnot foundと言われる時は暗号化キーのリージョンを確認してみてください。

```
$ aws kms encrypt --key-id alias/cloudwatch-alarm-to-slack --plaintext "hooks.slack.com/services/************************"

An error occurred (NotFoundException) when calling the Encrypt operation: Alias arn:aws:kms:ap-northeast-1:*********:alias/cloudwatch-alarm-to-slack is not found.
```




###関数作成
「cloudwatch-alarm-to-slack」にします(node.jsです)。
![スクリーンショット 2018-03-24 15.02.32.png](https://qiita-image-store.s3.amazonaws.com/0/86605/5743ba13-c394-509c-2ef9-ffbce9ec20ae.png)

###関数登録
以下のように登録しました。
![スクリーンショット 2018-03-24 15.32.47.png](https://qiita-image-store.s3.amazonaws.com/0/86605/bdaceb1a-9a11-3d94-9f70-c236bb8ebc9d.png)

![スクリーンショット 2018-03-24 15.32.56.png](https://qiita-image-store.s3.amazonaws.com/0/86605/318ad470-bb20-6fe8-62b4-47f2c14f33ac.png)

![スクリーンショット 2018-03-24 15.33.20.png](https://qiita-image-store.s3.amazonaws.com/0/86605/8e1eeec3-f747-153e-e636-a681c10d2e91.png)
「slackChannel」は流したいチャンネル。
「kmsEncryptedHookUrl」は暗号化したWebhookURLを設定する。

登録するとSlackにアラートが通知されるようになります。


###コード修正
processEvent()のslackMessageを編集することで通知メッセージをいじることができます。
以下のように設定しました。

```
function processEvent(event, callback) {
    const message = JSON.parse(event.Records[0].Sns.Message);

    const alarmName = message.AlarmName;
    //var oldState = message.OldStateValue;
    const newState = message.NewStateValue;
    const reason = message.NewStateReason;

    var stamp;
    if (newState === "ALARM") {
        stamp = ":warning:";
    } else {
        stamp = ":ok_woman:";
    }
    const slackMessage = {
        channel: slackChannel,
        text: `*${stamp} ${newState}: ${alarmName} ${stamp}*\n${reason}`,
    };
```

さらに、KMSキーで暗号化しない(無料枠で使う)場合は、[Lambdaのcloudwatch-alarm-to-slackで無料と思ってKMS暗号化キーを使ったら2円かかったので関数修正した](https://qiita.com/hf7777hi/items/6226a17ddfc17ad9268c)の通りLambdaの関数を修正するとOKです。

###確認
わざとNG、OKとなるようにいじってslackに届くか確認します。

![スクリーンショット 2018-03-24 16.03.29.png](https://qiita-image-store.s3.amazonaws.com/0/86605/f37cdb0f-655c-3827-696e-ef97fd8e318e.png)
Goodですね。

以上です。