ちょっと話題の記事

初めてのLambda

2016.03.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Lambdaって面白そうだなぁ、便利そうだなぁと思いつつも実際に構築した事が無かった菅野です。
Lambdaを使う案件が発生したのでちょっと使ってみました。

言語はnode.jsを使います。

今回の目標

  • EC2を1台用意し、webサーバーとして起動する
  • Lambdaでhttpポートを監視する(5分に1回チェック)
  • 監視で異常があった場合SNSへ通知する
  • SNSは携帯電話へメールを送信する

では早速構築していきます。

webサーバーを用意する

  • AmazonLinuxのインスタンスを作成する
  • インスタンスタイプはt2.nano、EBSはマグネティックというケチケチ構成で
  • 開けるポートはsshとhttpの二つのみ。
スクリーンショット 2016-03-25 15.23.27
  • 起動したらsshでログインしてapacheをインストールする
sudo yum install httpd24
  • viで監視用のファイルを作ります。内容は「OK」だけでOK
sudo vi /var/www/html/check.html
  • apacheを起動してブラウザで確認する
sudo service httpd start
スクリーンショット 2016-03-25 15.31.03

 SNSを使ってメールを送信する準備

  • topicを作成する
「Create new topic」ボタンをクリックする
「Topic name」に名前を入力(今回は「error_to_mail」としました)
スクリーンショット 2016-03-27 0.18.46
  • Subscriptionを作成する
作成したtopicのARNをクリックする
「Create Subscription」ボタンをクリックする
「Protocol」は「Email」を選択し、「」にメールアドレスを入力する
  • 確認メールが届くのでリンクをクリックする
これで今後、SNSからの通知メールが届くようになります

LambdaからSNSへの通知を許可する

  • ここではLambdaがSNSへ通知できるようにするためのIAMロールを作成しておきます
ロール名に名前を入力する(今回は「Lambda_to_SNS」としました)
ロールタイプは「AWS Lambda」を選択する
スクリーンショット 2016-03-25 16.28.39
ポリシーのアタッチでは「AmazonSNSFullAccess」を選択する
スクリーンショット 2016-03-25 16.29.33

Lambda関数を作成する

  • 本番です。まずは作成から
  • 最初に関数のサンプルを選ぶ画面(Select bluepoint)が表示されますがスルーします。
  • 関数の作成を行います
名前を入力する(今回は「http−check」としました)
「Lambda function handler and role」の「role」で先ほど作成したIAMロールを指定します
関数の入力欄に以下のソースをコピーして貼り付けます
(【IPアドレス】と【topicのarn】の部分は置き換えてください)
var AWS = require('aws-sdk');
var sns = new AWS.SNS();
var http = require( 'http' );

var url = 'http://【IPアドレス】/check.html';

exports.handler = function( event, context ) {

  var sendToSNS = function( message ) {
    // パラメーターを用意
    var params = {
      Message: message,
      TopicArn: '【topicのarn】'
    };

    // SNSへ通知
    sns.publish(
      params,
      function( err, data ) {
        if (err) context.fail( err.stack );
        else context.succeed( data );
      }
    );
  };

  // チェック用ページを取得
  http.get(
    url,
    function( res ) {
      if ( res.statusCode == 200 ) {
        context.done();
      }
      else {
        sendToSNS( 'error' );
      }
    }
  ).on(
    'error',
    function( e ) {
      sendToSNS( 'error' );
    }
  );

};
  • 関数の一覧で目的の関数をクリックし、表示される画面でテストします
スクリーンショット 2016-03-27 1.42.21

Lambda関数を自動で実行させる

  • 次に定期的に自動で実行するように仕込みます。実際に実行してくれるのはCloudWatch Eventsです
  • 先ほど作成したLambda関数をクリックし、「Event sources」タブを開きます
  • 「Add event source」をクリックする
  • 表示されたポップアップで以下を設定する
「Event source type」で「CloudWatch Events」を選択する
名前を入力する(今回は「http-check-event」としました)
「Schedule expression」で「rate(5 minutes)」を選択する
スクリーンショット 2016-03-25 17.46.16

自動で実行されるか確認

EC2のapacheのログで確認してみると、5分間隔でhttpアクセスがあった事が確認できました
スクリーンショット 2016-03-26 19.28.01

SNSへ通知されてメールが届くか確認

  • SNSへ通知させるため、webサーバーのapacheを止めてエラーを検知させます
sudo service httpd stop
  • しばらくすると監視結果がエラーになってメールが届きました。OKです。
IMG_3238

できましたね

Lambdaによるwebサーバーの監視ができました。
関数もnode.jsとAWSのDocumentのサンプルコードを少しいじっただけでほとんどそのままです。
また、今回構築してみたことで以下の事を学ぶ事ができました。
・Lambdaの作成方法
・Lambda関数内でのhttpアクセスとSNSへの通知の方法

勉強のために作ってみましたが、実際にはCloudWatch Eventsによる定期的な実行は最小間隔が5分なので

実用としては無理かなというのが感想です。

例えばLambda関数の中でループさせて〜sleepさせて〜とかやれば無理やり1分周期の確認が

できるかもしれませんが、それではLambda関数の実行時間が長くなるのでLambdaのメリットである
「ちょっと動かすからEC2不要で安い」という点が台無しです。
使うなら可能な限り無料枠で収めて使いたいですよね。

千葉 淳さんからご指摘を頂きました!

ClowdWatch Eventsを1分間隔で動かす方法がすでにDevelopers.IOにて公開されています!
これなら監視にも使えますね。勉強不足でした!

参考資料