LambdaとCloudWatch EventsでEC2の自動起動&自動停止をやってみた(Python版)

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

こんにちわ。ウィスキー「フロム・ザ・バレル」がどうしても「レイ・ザ・バレル」に聞こえてしまうガノタ市田です。

AWSのサイトにはナレッジセンター というページがあり、AWS利用に関する様々な情報が公開されています。 今回はナレッジセンターにある「定期的にEC2インスタンスの起動&停止を行う方法」 について紹介したいと思います。
最終的に、「指定のインスタンスを毎日09:00に起動して、毎日18:00に停止する」環境を作ります。ちなみに対象が複数インスタンスでも可能です。

概要

手順としては簡単で大きく分けると下記の3つになります。

  • Lambda Functionの作成
  • IAM Roleの作成
  • CloudWatch Eventsの作成

それでは見ていきたいと思います。

Lambda Functionの作成

インスタンス停止のlambda functionの作成

最初に停止用のFunctionを作成します。Lambdaの画面を開いて、「Blank Function」 をクリックします。

01-blankfunction

次の画面ではそのまま「Next」 をクリックします。

02-configure-triggers

次に関数を作っていきます。今回は下記のように指定しました。

  • NameStopEC2Instances を入力
  • Descriptionstops EC2 instances every day at night を入力
  • RuntimePython2.7 をプルダウンから選択

03-lambda-config

コードは下記の内容を設定します。 regioninstancesには、利用環境に合わせて変更してください。
東京リージョンの場合は、regionにはap-northeast-1を設定します。intancesには対象のインスタンスIDを設定します。複数のインスタンスを指定したい場合は、['X-XXXXXXXX', 'X-XXXXXXXX']と記載します。

import boto3

# Enter the region your instances are in, e.g. 'us-east-1'
region = 'XX-XXXXX-X'

# Enter your instances here: ex. ['X-XXXXXXXX', 'X-XXXXXXXX']
instances = ['X-XXXXXXXX']
def lambda_handler(event, context):
    ec2 = boto3.client('ec2', region_name=region)
    ec2.stop_instances(InstanceIds=instances)
    print 'stopped your instances: ' + str(instances)

IAM Roleの作成

次にLambdaが実行できるようにIAM Roleを割り当てます。今回は新規作成するので「Create a custom role」 を選択しました。
04-lambda-make-role

「Create a custom role」 を指定すると、IAMの画面が開きますので、続けて設定します。 設定は下記の通りです。

  • IAMロール「新しいIAMロールの作成」 を選択します。
  • ロール名「lambda_start_stop_ec2」 と入力しました。

次に「ポリシードキュメントを表示」 をクリックします。

05-make-role

「編集」 をクリックして、ポリシー内容を記載して「許可」 をクリックします。

06-edit-policy

ポリシー内容は以下です。

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

Lambda設定の続き

元のLambdaの画面に戻って「Next」 をクリックします。

07-advance

問題なければ「Create function」 をクリックします。

08-create-function

インスタンス起動のlambda functionの作成

同じようにインスタンス起動用 のFunctionを作っていきます。

09-create-start-function

各設定は、下記のようにしました。

  • NameStartEC2Instances を入力
  • Descriptionstart EC2 instances every day at morning を入力
  • RuntimePython2.7 をプルダウンから選択

10-start-config-function

コードは下記のとおりです。regioninstancesには、利用環境に合わせて変更してください。

import boto3

# Enter the region your instances are in, e.g. 'us-east-1'
region = 'XX-XXXXX-X'

# Enter your instances here: ex. ['X-XXXXXXXX', 'X-XXXXXXXX']
instances = ['X-XXXXXXXX']
def lambda_handler(event, context):
    ec2 = boto3.client('ec2', region_name=region)
    ec2.start_instances(InstanceIds=instances)
    print 'started your instances: ' + str(instances)

IAM Roleは先程作成したので、それをプルダウンから選択します。

11-role-advance

問題なければ「Create function」 をクリックします。 12-review

CloudWatch Eventsの設定

次にLambdaを呼び出すCloudWatch Eventsを設定していきます。
停止と起動用の2つを作ります。まずは停止用のイベントを作ります。 CloudWatchの画面で「イベント」 をクリックして「ルールの作成」 をクリックします。

13-cloudwatch-events

ルールを作ります。イベントの選択は下記のように設定します。

  • パターン:プルダウンから「スケジュール」 を選択します。
  • 設定「Cron式」 を選択して、0 9 * * ? * と設定しました。

14-schedule

このCron式の設定の意味は「毎日18:00」 という意味になります。またタイムゾーンはUTCになるのでJSTとの時間差に注意して設定してください。
cronの書式は、Unix系OSで利用するものとは若干異なるので注意してください。書式の詳細は下記の公式ドキュメントが参考になります。

Rate または Cron を使用したスケジュール式 - AWS Lambda

UTCとJSTの変換は下記が便利です。

時差計算

次にターゲットという形で、実行するLambda Functionを指定します。
プルダウンから「Lambda関数」 を選択し、実行したいLambda Functionを選択します。今回は停止用のイベント設定なので先程作成した「StopEC2Instances」 を選択します。

15-target

次の画面で、名前などを設定します。今回は下記のように設定しました。

  • 名前StopEC2Instances と入力
  • 説明stops EC2 instances every day at night と入力

これで「ルールの作成」 をクリックします。

16-detail-rule

続けて、起動用のイベントを作成します。

17-success-stop-rule

停止用の設定と同じように作成していきます。

  • パターン:プルダウンから「スケジュール」 を選択します。
  • 設定「Cron式」 を選択して、0 0 * * ? * と設定しました。
  • ターゲットStartEC2Instances を選択します。

Cronの設定は、毎日09:00 にインスタンスを起動する想定です。

18-start-rule

最後にイベント名などを設定します。

  • 名前StartEC2Instances と入力
  • 説明start EC2 instances every day at morning と入力

これで作業完了です。

確認

CloudWatch Eventsのログで確認することができます。

20-eventlog

上記のいずれかをクリックすると各ストリームが出てくるので、最新の内容を見たい場合は時刻が最新のものをクリックします。

21-log-stream

詳細画面を確認できます。下記の場合だと「START RequestId:xxxxxx」 でこのイベントがスタートしたことが記録されています。
次の行ではLambda Functionのコードで指定した内容が出力されていて、正常にLambdaが実行されたことが確認できます。

22-datail-log

最後に

Lambdaは便利ですね。今回の手順はとても簡単なので是非活用してCost Efficiency にAWSを使っていきましょう!

以上です。