【AWS RDS落ちた…】CloudWatchのアラームを社内Slackに通知するまでの方法

ある日突然、RDSが落ちた…

弊社は、開発環境にCloud9を使用し、データベースは、開発環境共用のRDSを使用しています。 最近、社員数が大幅に増えてRDSの容量が不足して、RDSが落ちる現象が発生しました。

容量不足を事前に把握できていなかった

なので、容量が不足する前に、把握できるよう、CloudWatchでRDSのアラームをした上で、社内のSlackに通知する設定をしました。

設定にあたりこの記事を参考にさせてもらいました。 qiita.com

設定の前に

まずは各DBどれくれいの容量を使用しているかチェック 必要ないものは削除して、これだけでもかなりの容量不足を解消できました。

SELECT 
table_schema, sum(data_length) /1024/1024 AS mb 
FROM 
information_schema.tables 
GROUP BY 
table_schema 
ORDER BY 
sum(data_length+index_length) DESC;

CloudWatchの設定

CloudWatchのダッシュボードにRDSの情報を追加 CPU,メモリ,容量くらいは入れとくことにしました。

  • CPUUtilization
  • FreeableMemory
  • DatabaseConnections
  • FreeStorageSpace
  • SwapUsage

ローカルにawsCLIのインストール

$ aws

で確認するとインストールされていなかったのでインストール

Pythonのversion確認

$ python --version

awscliのインストール

$ curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip" unzip awscli-bundle.zip
$ sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
$ ./awscli-bundle/install -h

インストールできたか確認

$ aws --version

初期設定

$ ls ~/.aws
$ aws configure

※自分自身のIAMでアクセスキーを設定します。

SNSの設定*1

AWSコンソールにログインします。 名前と表示名を設定してトピックの作成

プロトコルとエンドポイントを設定して、メールの通知設定 f:id:Vitalize:20200217130819p:plain f:id:Vitalize:20200217115302p:plain

cloudwatchの設定

アラームを作っていきます f:id:Vitalize:20200217114516p:plain f:id:Vitalize:20200217114628p:plain f:id:Vitalize:20200217115020p:plain f:id:Vitalize:20200217115121p:plain

テスト通知

ローカルで次のコマンドを入力すると、メールに通知がきます。

$ aws cloudwatch set-alarm-state --alarm-name "rds_CPUUtilization" --state-value ALARM --state-reason "alarm-test" --profile default

slackの設定

通知したいチャンネルに Incoming WebHooks を追加します。 f:id:Vitalize:20200217115512p:plain

KMSの設定

f:id:Vitalize:20200217115558p:plain ・キー管理・使用アクセス許可は適宜追加します。 ・ARNはあとで使います。

Lambdaの設定

適宜やります f:id:Vitalize:20200217115951p:plain f:id:Vitalize:20200217120107p:plain f:id:Vitalize:20200217120850p:plain f:id:Vitalize:20200217121010p:plain f:id:Vitalize:20200217121255p:plain 関数の作成を押す。

コードを編集します。

- HOOK_URL = "https://" + boto3.client('kms').decrypt(CiphertextBlob=b64decode(ENCRYPTED_HOOK_URL))['Plaintext'].decode('utf-8')
+ HOOK_URL = boto3.client('kms').decrypt(CiphertextBlob=b64decode(ENCRYPTED_HOOK_URL))['Plaintext'].decode('utf-8')
alarm_name = message['AlarmName']
#old_state = message['OldStateValue']
new_state = message['NewStateValue']
reason = message['NewStateReason']
+ alarm_description = message['AlarmDescription']
- 'text': "%s state is now %s: %s" % (alarm_name, new_state, reason)
+ 'text': "<!here> \nアラーム名: %s\nステータス: %s\nアラーム理由: %s\n説明: %s" % (alarm_name, new_state, reason, alarm_description)

iamロールの修正

IAMから →ロール →cloudwatch-alerm-to-slack →AWSLambdaKMSExecutionRole-[hogehoge] →ポリシーの編集 →JSON

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1443036478000",
"Effect": "Allow",
"Action": [
"kms:Decrypt"
],
"Resource": [
"<4でコピーした ARN>"
]
}
]
}

もう一度テスト

ローカルに戻って、次のコマンドを入力すると、slackにも通知がきます。

$ aws cloudwatch set-alarm-state --alarm-name "rds_CPUUtilization" --state-value ALARM --state-reason "alarm-test" --profile default

これで通知が来るようになります。

f:id:Vitalize:20200217121658p:plain

できた!

執筆:小杉

*1:Amazon Simple Notification Service

株式会社Vitalize