LambdaのScheduleイベントでEC2を自動起動&自動停止してみた#reinvent

AmazonLambda
119件のシェア(ちょっぴり話題の記事)

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

はじめに

Lambdaがアップデートされ、スケジュール機能が使えるようになりました。
当ブログでも紹介されています。

【速報】AWS Lambdaの機能拡張が数多くきました!VPC対応、ロングランニング、スケジュール、バージョニング、Python対応! #reinvent

AWS Lambda の Scheduled Event を試してみた #reinvent

皆さんは日中帯や平日のみ使うサーバをお持ちでしょうか。
開発用のインスタンスであれば、業務時間だけ使えればOKなんて事もあるかと思います。
スケジュール機能を使ってEC2インスタンスを自動起動&自動停止してみました。

セットアップ手順

Lambda Functionの作成

LambdaのWEBコンソールにて、「Create a Lamdba function」を選択します。

AWS_Lambda

Step 1: Select blueprintは、[Skip]します。

Step 2: Configure functionで、Lambda Functionの設定を行っていきます。
キャプチャは起動のものとなります。停止はstartをstopに置き換えて下さい。

AWS_Lambda1

Function Codeをコピー&ペーストします。
Function CodeのインスタンスIDとリージョンは適宜記載して下さい。

□ 起動用Function Code

const INSTANCE_ID = '*****';

var AWS = require('aws-sdk'); 
AWS.config.region = '*****';

function ec2Start(cb){
    var ec2 = new AWS.EC2();
    var params = {
        InstanceIds: [
            INSTANCE_ID
        ]
    };
 
    ec2.startInstances(params, function(err, data) {
        if (!!err) {
            console.log(err, err.stack);
        } else {
            console.log(data);
            cb();
        }
    });
}
exports.handler = function(event, context) {
    console.log('start');
    ec2Start(function() {
        context.done(null, 'Started Instance');
    });
};

□ 停止用Function Code

const INSTANCE_ID = '*****';

var AWS = require('aws-sdk'); 
AWS.config.region = '*****';

function ec2Stop(cb){
    var ec2 = new AWS.EC2();
    var params = {
        InstanceIds: [
            INSTANCE_ID
        ]
    };
 
    ec2.stopInstances(params, function(err, data) {
        if (!!err) {
            console.log(err, err.stack);
        } else {
            console.log(data);
            cb();
        }
    });
}
exports.handler = function(event, context) {
    console.log('start');
    ec2Stop(function() {
        context.done(null, 'Stoped Instance');
    });
};

Roleでは、[Basic execution role]を選択します。

AWS_Lambda2

IAMロールの設定画面に遷移します。
[Create a new IAM Role]を選択し、適切な[Role Name]を入力します。
[View Policy Document]を押下すると、ポリシーが表示されます。

AWS_Lambda8

[Edit]を選択しポリシーを入力します。入力後[Allow]を押下します。
ブラウザの設定でポップアップがブロックになっていたところ、上手くいきませんでした。
操作が上手くいかない場合はご確認ください。

AWS_Lambda9

□ 起動用ポリシー

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents",
        "ec2:StartInstances"
      ],
      "Resource":[
      "arn:aws:logs:*:*:*",
      "arn:aws:ec2:*"
      ]
    }
  ]
}

□ 停止用ポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "ec2:StopInstances"
            ],
            "Resource": [
                "arn:aws:logs:*:*:*",
                "arn:aws:ec2:*"
            ]
        }
    ]
}

Advanced settingsはデフォルト値としました。 AWS_Lambda10

問題がなければ、[Create function]を押下します。 AWS_Lambda11

Functionのテスト

起動テストを実行します。
対象のインスタンスが停止している状態で、Testボタンを押下します。
インスタンスが起動したら、OKです。停止も同様にテストします。

AWS_Lambda6

EventSource設定

[Event sources]タブを開き[Add event source]を選択します。

AWS_Lambda20

21時40分に起動されるように設定しました。停止の場合も同様に設定して下さい。
時刻の指定方法はこちらを参照ください。

AWS_Lambda14

自動起動&停止の確認

EC2のWEBコンソールを確認すると、起動したことがわかります。
CloudTrailには、以下のように記録されました。

AWS_Lambda18

停止の場合、CloudTrailには以下のように記録されました。

AWS_Lambda19

おわりに

EC2インスタンスの自動起動&停止を試してみました。
料金削減などにお役立ていただけると嬉しいです。

  • 新米IT技術者

    はじめまして、新米IT技術者です。
    現在AWS関連の実務を行っており、こちらのページを参考にさせて頂いております。
    2016年12月2日現在のAWS Lambdaと掲載されているLambdaで差異があるのですが、ほぼ同様の手順で
    作成しているのですが動作しない状況です。色々と調べてみたのですが解決出来ないでおります。
    掲載されているサンプルソースで作成しますと、
    「Congratulations! Your Lambda function “Start-EC2-Instance” has been successfully created and configured with Scheduled Event: START-EC2-INSTANCE as a trigger. You can now click on the “Test” button to input a test event and test your function.」
    と表示されて問題無いように思います。ですが実際に”Test”ボタンをクリックすると
    「InvalidCharacterError」
    TESTボタンを押下した時に表示されるInput test eventはデフォルトの「Hello World」を内容を変更せず使っています。
    (ここに問題があるのかもしれませんが・・・)
    となってしまい動作の確認がとれません。サンプルコードのINSTANCE_ID、regionはこちらの環境に設定しております。突然のお願いで大変恐縮ですが何かお分かりになりましたらご教示頂きたく存じます。よろしくお願いいたします。