AWS

AWS CloudWatch+SNS+Lambda+Serverless Framework+Chatwork API

 

Serverlessフレームワークを利用して

 

  • Lambdaアプリケーション, Lambda関数の作成
  • SNSの作成 + SNSとLambda関数との連携
  • 上記のデプロイ

これが出来ます。

 

通知の流れ

 

  • Cloudwatch Alarm → SNS → Lambda → Chatwork

 

動作

  1. Cloudwatch Alarmで設定したメトリクスに対して、警告時にSNSトピックスに通知する
  2. SNSはLambdaを叩く
  3. LambdaはChatwork APIを通してルームIDを指定したルームに投稿

 

 

クライアント側の作業をします

 

# python --version
Python 2.7.14

 

Python3のインストール

$ sudo yum install python3

Installed:
  python3.x86_64 0:3.7.3-1.amzn2.0.1

Dependency Installed:
  python3-libs.x86_64 0:3.7.3-1.amzn2.0.1                            python3-pip.noarch 0:9.0.3-1.amzn2.0.1
  python3-setuptools.noarch 0:38.4.0-3.amzn2.0.6

Complete!

 

バージョンの確認

$ python3 --version
Python 3.7.3

Python 3.7を確認

 

 

AWS CLI

 

AWS CLIのインストール

# curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
# python get-pip.py
# pip install awscli

 

設定を行います

# aws configure

AWS Access Key ID [None]: xxxxxxxxxxxxx
AWS Secret Access Key [None]: xxxxxxxxxxxxxxxxxxxx
Default region name [None]: ap-northeast-1
Default output format [None]: json

 

設定の確認

# aws configure list

      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************7BIA shared-credentials-file
secret_key     ****************bA4M shared-credentials-file
    region           ap-northeast-1      config-file    ~/.aws/config

 

 

Node.js

 

$ sudo su -

# yum -y install gcc-c++ git
# git clone https://github.com/creationix/nvm.git ~/.nvm

 

パスを通す

# source ~/.nvm/nvm.sh

 

$ nvm ls-remote

mkdir: cannot create directory ‘/home/ec2-user/.nvm/alias’: Permission denied
mkdir: cannot create directory ‘/home/ec2-user/.nvm/alias’: Permission denied
        v0.1.14
        v0.1.15
        v0.1.16
        v0.1.17

 

 

$ nvm install v8.10.0

Downloading and installing node v8.10.0...
Downloading https://nodejs.org/dist/v8.10.0/node-v8.10.0-linux-x64.tar.xz...
######################################################################################################################## 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v8.10.0 (npm v5.6.0)
Creating default alias: default -> v8.10.0

 

バージョンの確認

# node -v
v8.10.0

 

ローカルでLambdaスクリプト実行する為のライブラリ
# pip install python-lambda-local

デプロイテストで利用するライブラリ
# pip install python-levenshtein

 

Serverlessフレームワーク

 

インストール

# npm install -g serverless

 

Serverlessフレームワークのテストをします。

# sls create -t aws-python -p slstest

Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/root/slstest"
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v1.44.1
 -------'

Serverless: Successfully generated boilerplate for template: "aws-python"

 

デプロイ

# sls deploy

 

helloファンクションの実行

# sls invoke -f hello

{
    "body": "{\"input\": {}, \"message\": \"Go Serverless v1.0! Your function executed successfully!\"}",
    "statusCode": 200
}

ヴァージニアリージョンにアクセスするとLambda関数がセットされており、Serverlessフレームワークできちんとデプロイできていることがわかります。

 

 

Chatwork通知用の関数を作成

@see https://dev.classmethod.jp/server-side/sls-lambda-chatwork/

クラスメソッドさんが既に作ってあるのでこれを頂きます。

 

# sls create -t aws-python3 -p chatwork-cloudwatch

Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/root/chatwork-cloudwatch"
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v1.44.1
 -------'

Serverless: Successfully generated boilerplate for template: "aws-python3"

 

必要なライブラリ「serverless-python-requirements」をインストール

# cd chatwork-cloudwatch
# npm install --save serverless-python-requirements

 

コンフィデンシャル設定

# vi ~/.aws/credentials

[default]
aws_access_key_id=xxxxxxxxxxxxxxxxx
aws_secret_access_key=xxxxxxxxxxxxxxxxxxxx
output = json
region = ap-northeast-1

IAMユーザでAdminfullAccessのポリシーのユーザを指定しています。

 

全体の設定

# vi serverless.yml


service: chatwork-cloudwatch

provider:
  name: aws
  runtime: python3.7 #←●Pythonのバージョンを合わせること
  region: ap-northeast-1
  profile: default #←●参照するコンフィデンシャルのプロフィール名

  environment:
    CHATWORK_API_KEY: xxxxxxxxxxxxxxxxxxxx #←●Chatwork API Keyを指定
    CHATWORK_HEADER: X-ChatWorkToken
    CHATWORK_ROOM_ID: xxxxxxxxx #←●ChatworkルームIDを指定
    CHATWORK_URL: https://api.chatwork.com/v2

plugins:
  - serverless-python-requirements


functions:
  dispatcher: # file_name
    handler: dispatcher.dispatch #←●ハンドラ名.関数
    events:
      - sns: sls-cloudwatch #←●作成するSNSトピック名を指定

 

 

 

# vi dispatcher.py


import json
import logging
import requirements
import requests
import urllib
import os
 
 
logger = logging.getLogger()
logger.setLevel(logging.INFO)
 
message_header  = "============ Alart ===========\n"
 
def dispatch(event, context):
    logger.info("Event: " + str(event))
    message = json.loads(event['Records'][0]['Sns']['Message'])
    logger.info("Message: " + str(message))
 
    # 環境変数から情報取得
    CHATWORK_API_KEY = os.environ['CHATWORK_API_KEY']
    CHATWORK_HEADER = os.environ['CHATWORK_HEADER']
    CHATWORK_ROOM_ID = os.environ['CHATWORK_ROOM_ID']
    CHATWORK_URL = os.environ['CHATWORK_URL']
 
    # Chatwork APIを利用するためのURL
    URL = '{0}/rooms/{1}/messages'.format(CHATWORK_URL,CHATWORK_ROOM_ID)
 
 
    # メッセージ取得
    chatwork_message = get_cloudwatch_message(message)
    payload = {'body': chatwork_message}
    headers = {CHATWORK_HEADER: CHATWORK_API_KEY}
 
    try:
        # Chatworkに投稿
        requests.post(URL, headers=headers, params=payload)
    except:
        logger.info("Failed! Message : \n" + str(chatwork_message))
    else:
        logger.info("Success! Message posted to: \n" + str(chatwork_message))
 
 
def get_cloudwatch_message(data):
    logger.info("get data: " + str(data))
 
    # 渡ってきたデータからほしい情報を抽出
    alarm_name = data['AlarmName']
    new_state = data['NewStateValue']
    reason = data['NewStateReason']
    metric_name = data['Trigger']['MetricName']
    target_name = data['Trigger']['Dimensions'][0]['name']
    target_value = data['Trigger']['Dimensions'][0]['value']
 
    # Chatworkに投稿したいメッセージ
    chatwork_message = '{0}\n\
    アラーム名:{1} \n\
    new_state:{2} \n\
    reason:{3} \n\
    metric_name - {4} \n\
    target_name - {5} \n\
    target_value - {6}'.format(message_header,alarm_name,new_state,reason,metric_name,target_name,target_value)
    return chatwork_message

 

※Chatworkにrequestライブラリで送るのに必要なコード

import requests
payload = {'body': '<メッセージ>'}
headers = {'X-ChatWorkToken': 'YOUR CHATWORK TOKEN'}
requests.post('https://api.chatwork.com/v1/rooms/****/messages', headers=headers, params=payload)

 

 

 

必要なライブラリを記述します

# vi requirements.txt

requests

 

# vi requirements.py


import os
import sys
 
 
requirements = os.path.join(
    os.path.split(__file__)[0],
    '.requirements',
)
 
if requirements  not in sys.path:
    sys.path.append(requirements)

 

デプロイ

# sls deploy -v


Serverless: Generated requirements from /root/chatwork-cloudwatch/requirements.txt in /root/chatwork-cloudwatch/.serverless/requirements.txt...
Serverless: Installing requirements from /root/chatwork-cloudwatch/.serverless/requirements/requirements.txt ...
Serverless: Running ...
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Injecting required Python packages to package...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
CloudFormation - CREATE_IN_PROGRESS - AWS::CloudFormation::Stack - chatwork-cloudwatch-dev
CloudFormation - CREATE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - CREATE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - CREATE_COMPLETE - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - CREATE_COMPLETE - AWS::CloudFormation::Stack - chatwork-cloudwatch-dev
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service chatwork-cloudwatch.zip file to S3 (1.95 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - chatwork-cloudwatch-dev
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - DispatcherLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - DispatcherLogGroup
CloudFormation - CREATE_COMPLETE - AWS::Logs::LogGroup - DispatcherLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_COMPLETE - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - DispatcherLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - DispatcherLambdaFunction
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Function - DispatcherLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - DispatcherLambdaPermissionRDSDiskCheckAlertSNS
CloudFormation - CREATE_IN_PROGRESS - AWS::SNS::Topic - SNSTopicRDSDiskCheckAlert
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - DispatcherLambdaPermissionRDSDiskCheckAlertSNS
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - DispatcherLambdaVersionP57YI0boyhmGea9ZOcUhTZoHvhE7X6VriQ9CQxhCLn8
CloudFormation - CREATE_IN_PROGRESS - AWS::SNS::Topic - SNSTopicRDSDiskCheckAlert
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - DispatcherLambdaVersionP57YI0boyhmGea9ZOcUhTZoHvhE7X6VriQ9CQxhCLn8
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Version - DispatcherLambdaVersionP57YI0boyhmGea9ZOcUhTZoHvhE7X6VriQ9CQxhCLn8
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Permission - DispatcherLambdaPermissionRDSDiskCheckAlertSNS
CloudFormation - CREATE_COMPLETE - AWS::SNS::Topic - SNSTopicRDSDiskCheckAlert
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - chatwork-cloudwatch-dev
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - chatwork-cloudwatch-dev
Serverless: Stack update finished...
Service Information
service: chatwork-cloudwatch
stage: dev
region: ap-northeast-1
stack: chatwork-cloudwatch-dev
resources: 7
api keys:
  None
endpoints:
  None
functions:
  dispatcher: chatwork-cloudwatch-dev-dispatcher
layers:
  None

Stack Outputs

(略)

Serverless Enterprise: Run `serverless login` and deploy again to explore, monitor, secure your serverless project for free.

 

デプロイによって下記が出来ています。

  • Lambda関数のデプロイ
  • SNSとLambda関数の連携とデプロイ

 

Cloudwatch Alarm

 

今回はRDSの容量を監視します。

 

Cloudwatch Alarmの作成を行います。

 

  • メトリクス
    「FreeStorageSpace」を選択します。
  • ディスク容量の閾値を設定します。
    FreeStorageSpace (FreeStorageSpace) <= 3000000000
    ※ 3000000000 = 3GB
  • アラームが次の時
    「警告」
  • SNSのトピック
    「sls-cloudwatch」

 

Chatworkに通知が行くかテストする

 

RDSの容量をCloudwatch Alarmの警告閾値まで減らします。

 

EC2からRDSに接続します

# mysql -u <DBマスターユーザ> -h <RDSエンドポイント> -p

Enter password:<RDSパスワード>
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.22-log Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

 

 

MySQL [(none)]> show databases;

+--------------------+
| Database           |
+--------------------+
| information_schema |
| innodb             |
| mysql              |
| performance_schema |
| sys                |
| yuutestdb          |
+--------------------+
6 rows in set (0.00 sec)

yuutestdbがターゲットです。

 

MySQL [(none)]> USE yuutestdb;
Database changed

 

CREATE TABLE item (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(10),
  description VARCHAR(30),
  price INT UNSIGNED,
  created_at DATETIME
);

 

INSERT INTO item () VALUES (); --1行作成
INSERT INTO item (id) SELECT 0 FROM item; --2行になる
INSERT INTO item (id) SELECT 0 FROM item; --4行になる
INSERT INTO item (id) SELECT 0 FROM item; --8行になる
INSERT INTO item (id) SELECT 0 FROM item; --16行になる

・・・
繰り返す

 

データを入れ込む

UPDATE item SET
  name = CONCAT('商品', id),
  description = SUBSTRING(MD5(RAND()), 1, 30),
  price = CEIL(RAND() * 10000),
  created_at = ADDTIME(CONCAT_WS(' ','2014-01-01' + INTERVAL RAND() * 180 DAY, '00:00:00'), SEC_TO_TIME(FLOOR(0 + (RAND() * 86401))));

 

これでRDSの容量が圧迫されます。

通知されたら成功です。

 

[amazon_link asins=’4295006653,4822237443,B07HJ12LJT’ template=’ProductCarousel’ store=’izayoi55-22′ marketplace=’JP’ link_id=’3840eb13-f1e4-4150-9a4f-afa11efd6458′]

 

 

[amazon_link asins=’4046042036,B07M7S9GDL,479739739X’ template=’ProductCarousel’ store=’izayoi55-22′ marketplace=’JP’ link_id=’d4bbfa38-ac08-4933-9c99-04dc3ba4b9ee’]

 

 

Amazonおすすめ

iPad 9世代 2021年最新作

iPad 9世代出たから買い替え。安いぞ!🐱 初めてならiPad。Kindleを外で見るならiPad mini。ほとんどの人には通常のiPadをおすすめします><

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)