LoginSignup
1
3

More than 5 years have passed since last update.

カスタムメトリクスをLambdaとCloudWatch Eventsを使って取得する

Last updated at Posted at 2016-11-09

目的

業務でCentOS 6.8のディスク監視が必要になったため普通にカスタムメトリクスで設定すればよいでしょ、と思っていたらちょっとはまったのでそのメモ書き

そもそもカスタムメトリクスとは?

EC2は標準でCloudWatchにいくつかのメトリクスを送信します。
その中には、CPU使用率やステータスチェックの結果などがあります。
※詳細はこちら
ただ、今回監視したいディスクの容量については標準のメトリクスには含まれないため、カスタムメトリクスとなります。

構成

カスタムメトリクス用のスクリプトをEC2に仕込んでCRONに登録してもよいのですが、今回は以下のように実現しました。

image

1.CloudWatch Eventsで5分おきにLambdaを呼び出す
2.LambdaでSSM経由でEC2内のカスタムメトリクス用スクリプトをキックする
3.ディスクの使用率をCloudWatchにPUTする

IAMロールの準備

EC2およびLambdaに権限を与えるためのロールを作成します。

今回はできるだけ権限を絞ろうと思い、必要のない権限を削除していますが(まだ削除できるかもしれない)、以下ドキュメントに従って設定したほうが間違いはないです。

Amazon EC2 Run Command へのアクセスの委任

EC2用ロールのポリシー

EC2用のロールを作成し、以下ポリシーを与えてください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1478653320000",
            "Effect": "Allow",
            "Action": [
                "ssm:DescribeAssociation",
                "ssm:GetDocument",
                "ssm:ListAssociations",
                "ssm:UpdateAssociationStatus",
                "ssm:UpdateInstanceInformation",
                "ec2messages:AcknowledgeMessage",
                "ec2messages:DeleteMessage",
                "ec2messages:FailMessage",
                "ec2messages:GetEndpoint",
                "ec2messages:GetMessages",
                "ec2messages:SendReply",
                "cloudwatch:PutMetricData",
                "ec2:DescribeInstanceStatus"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

Lambda用IAMロールのポリシー

Lambda用のロールには以下ポリシーを与えてください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:ListDocuments",
                "ssm:DescribeDocument",
                "ssm:GetDocument",
                "ssm:DescribeInstanceInformation",
                "ssm:SendCommand",
                "ssm:CancelCommand",
                "ssm:ListCommands",
                "ssm:ListCommandInvocations",
                "ec2:DescribeInstanceStatus",
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}

EC2の準備

今回Cent OS6.8ということでEC2をAWS Marketplaceの「CentOS 6 (x86_64) - with Updates HVM」から作成します。
インスタンス作成時には作成したEC2用ロールの付与を忘れないように!!

カスタムメトリクスの設定

インスタンスが立ち上がったらターミナルでインスタンスにログインします。

6.7から6.8へ

起動後にバージョンを確認すると、

[root@ip-10-0-0-82 ~]# cat /etc/redhat-release
CentOS release 6.7 (Final)

デフォルトではバージョン6.7になっているので、以下コマンドでupdateを行います。

[root@ip-10-0-0-82 ~]# yum update -y

update後のバージョンは6.8になりました。

[root@ip-10-0-0-82 ~]# cat /etc/redhat-release
CentOS release 6.8 (Final)

必要パッケージのインストール

はじめは以下の「Red Hat Enterprise Linux」を参考に設定していたのですが、どうもうまくいかずはまりました。

Amazon EC2 Linux インスタンスのメモリとディスクのメトリクスのモニタリング

AWSサポートにも問い合わせたところ、

CentOS でのサポートはしておらず、AWSからドキュメントとして提供しているものはございません

とのことだったので、スクリプトを自前で用意しようと思ったのですが、以下でいけました。

[root@ip-10-0-0-82 ~]# yum -y install perl-CPAN perl-libwww-perl openssl-devel perl-Crypt-SSLeay
[root@ip-10-0-0-82 ~]# yum -y install zip unzip wget

CloudWatch Monitoring Scriptsのインストール

現行バージョン(v1.2.1)は動かなかったため、v1.1.0を以下で導入しました。

[root@ip-10-0-0-82 ~]# mkdir /usr/local/cloudwatch
[root@ip-10-0-0-82 ~]# cd /usr/local/cloudwatch
[root@ip-10-0-0-82 cloudwatch]# wget http://ec2-downloads.s3.amazonaws.com/cloudwatch-samples/CloudWatchMonitoringScripts-v1.1.0.zip
[root@ip-10-0-0-82 cloudwatch]# unzip CloudWatchMonitoringScripts-v1.1.0.zip
[root@ip-10-0-0-82 cloudwatch]# rm CloudWatchMonitoringScripts-v1.1.0.zip

テスト

テストします。

[root@ip-10-0-0-82 cloudwatch]# cd aws-scripts-mon
[root@ip-10-0-0-82 aws-scripts-mon]# ./mon-put-instance-data.pl --mem-util --mem-used --mem-avail --verify

問題なければ

Verification completed successfully. No actual metrics sent to CloudWatch.

が返ってきます。

SSMエージェントインストール

以下に従いインストールします。

SSM エージェントのインストール

今回はバージニアリージョンにインスタンスを立てたので、amazon-ssm-us-east-1.としています。
東京リージョンにインスタンスを立てる際は、amazon-ssm-ap-northeast-1.としてください。

[root@ip-10-0-0-82 aws-scripts-mon]# cd /tmp
[root@ip-10-0-0-82 tmp]# curl https://amazon-ssm-us-east-1.s3.amazonaws.com/latest/linux_amd64/amazon-ssm-agent.rpm -o amazon-ssm-agent.rpm
[root@ip-10-0-0-82 tmp]# yum install -y amazon-ssm-agent.rpm
[root@ip-10-0-0-82 tmp]# rm amazon-ssm-agent.rpm

これでインスタンス内部の設定は終わりなのでログアウトしてOKです。

Lambdaの準備

CloudWatch EventsをトリガーにEC2にコマンドを実行するLambdaファンクションを作成します。

設定

設定値は以下の通りです。

項目 設定値
Runtime Node.js 4.3
Handler index.handler
Role 作成したLambda用ロール
Memory 128 MB
Timeout 10 sec

コード

コードは以下の通りです。
ディスクだけでなくメモリ等も監視したければ、commandsを変更してください。

'use strict';

const AWS = require('aws-sdk');
const ssm = new AWS.SSM();

exports.handler = (event, context, callback) => {

    const generator  = (function *() {

        try {
            const commands = [
                '/usr/local/cloudwatch/aws-scripts-mon/mon-put-instance-data.pl --disk-space-util --disk-path=/ --from-cron'
            ];

            yield sendCommand(event.instanceIds, commands, generator);

            callback(null, 'success');

        } catch (e) {
            callback(e.message);
        }
    })();

    /* 処理開始 */
    generator.next();

};

function sendCommand(instanceIds, commands, generator) {

    const params = {
        DocumentName: 'AWS-RunShellScript', /* required */
        InstanceIds: instanceIds,
        Parameters: {
            commands: commands,
            executionTimeout: [
                '300'
            ]
        },
        TimeoutSeconds: 600
    };

    ssm.sendCommand(params, function(err, data) {
        if (err) {
            console.log(err, err.stack);
            generator.throw(new Error('send command error : ' + params.InstanceIds));
            return;
       }
       console.log('successful send command : ' + params.InstanceIds);
       generator.next();
    });
}

CloudWatch Eventsの設定

定期的にカスタムメトリクス用スクリプトを実行するためのイベントを作成します。

[CloudWatch] - [ルール] - [ルールの作成]から新しくルールを作成します。

cloudwatchEvents_001.PNG

ターゲットでは、作成したLambdaファンクションを指定し、[入力の設定] - [定数 (JSON テキスト)]に以下を入力してください。

{"instanceIds":["i-xxxxxxxx","i-oooooooo"]}

i-xxxxxxxx、i-ooooooooにはスクリプトを実行する(SSMエージェントインストール済みの)インスタンスIDを入力します。

動作確認

ちゃんと動いているか確認します。

[CloudWatch] - [メトリックス] - [Linux システム]を選択します。

cloudwatchEvents_002.PNG

[Filesystem, InstanceId, MountPath]を選択します。

cloudwatchEvents_003.PNG

参照したいインスタンスのボリュームを選択するときちんとディスク使用率がPUTされていることがわかります。

cloudwatchEvents_004.PNG

以上

CentOS 6.8での需要はあまりないかもしれませんが、CloudWatch EventsからLambdaを呼び出してカスタムメトリクスを取得する流れは汎用的だと思います。
ポリシー周りで余計なもの等ありましたら(あるはず)ご指摘お願いします。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3