LambdaとCloudWatch EventsでEC2の自動起動&自動停止をやってみた(Python版)
こんにちわ。ウィスキー「フロム・ザ・バレル」がどうしても「レイ・ザ・バレル」に聞こえてしまうガノタ市田です。
AWSのサイトにはナレッジセンター というページがあり、AWS利用に関する様々な情報が公開されています。 今回はナレッジセンターにある「定期的にEC2インスタンスの起動&停止を行う方法」 について紹介したいと思います。 最終的に、「指定のインスタンスを毎日09:00に起動して、毎日18:00に停止する」環境を作ります。ちなみに対象が複数インスタンスでも可能です。
- AWS Support - Knowledge Center
- Start and Stop Instances at Scheduled Intervals Using Lambda and CloudWatch
概要
手順としては簡単で大きく分けると下記の3つになります。
- Lambda Functionの作成
- IAM Roleの作成
- CloudWatch Eventsの作成
それでは見ていきたいと思います。
Lambda Functionの作成
インスタンス停止のlambda functionの作成
最初に停止用のFunctionを作成します。Lambdaの画面を開いて、「Blank Function」 をクリックします。
次の画面ではそのまま「Next」 をクリックします。
次に関数を作っていきます。今回は下記のように指定しました。
- Name:StopEC2Instances を入力
- Description:stops EC2 instances every day at night を入力
- Runtime:Python2.7 をプルダウンから選択
コードは下記の内容を設定します。
region
とinstances
には、利用環境に合わせて変更してください。
東京リージョンの場合は、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」 を選択しました。
「Create a custom role」 を指定すると、IAMの画面が開きますので、続けて設定します。 設定は下記の通りです。
- IAMロール:「新しいIAMロールの作成」 を選択します。
- ロール名:「lambda_start_stop_ec2」 と入力しました。
次に「ポリシードキュメントを表示」 をクリックします。
「編集」 をクリックして、ポリシー内容を記載して「許可」 をクリックします。
ポリシー内容は以下です。
{ "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」 をクリックします。
問題なければ「Create function」 をクリックします。
インスタンス起動のlambda functionの作成
同じようにインスタンス起動用 のFunctionを作っていきます。
各設定は、下記のようにしました。
- Name:StartEC2Instances を入力
- Description:start EC2 instances every day at morning を入力
- Runtime:Python2.7 をプルダウンから選択
コードは下記のとおりです。region
とinstances
には、利用環境に合わせて変更してください。
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は先程作成したので、それをプルダウンから選択します。
問題なければ「Create function」 をクリックします。
CloudWatch Eventsの設定
次にLambdaを呼び出すCloudWatch Eventsを設定していきます。 停止と起動用の2つを作ります。まずは停止用のイベントを作ります。 CloudWatchの画面で「イベント」 をクリックして「ルールの作成」 をクリックします。
ルールを作ります。イベントの選択は下記のように設定します。
- パターン:プルダウンから「スケジュール」 を選択します。
- 設定:「Cron式」 を選択して、
0 9 * * ? *
と設定しました。
このCron式の設定の意味は「毎日18:00」 という意味になります。またタイムゾーンはUTCになるのでJSTとの時間差に注意して設定してください。 cronの書式は、Unix系OSで利用するものとは若干異なるので注意してください。書式の詳細は下記の公式ドキュメントが参考になります。
Rate または Cron を使用したスケジュール式 - AWS Lambda
UTCとJSTの変換は下記が便利です。
次にターゲットという形で、実行するLambda Functionを指定します。 プルダウンから「Lambda関数」 を選択し、実行したいLambda Functionを選択します。今回は停止用のイベント設定なので先程作成した「StopEC2Instances」 を選択します。
次の画面で、名前などを設定します。今回は下記のように設定しました。
- 名前:StopEC2Instances と入力
- 説明:stops EC2 instances every day at night と入力
これで「ルールの作成」 をクリックします。
続けて、起動用のイベントを作成します。
停止用の設定と同じように作成していきます。
- パターン:プルダウンから「スケジュール」 を選択します。
- 設定:「Cron式」 を選択して、
0 0 * * ? *
と設定しました。 - ターゲット:StartEC2Instances を選択します。
Cronの設定は、毎日09:00 にインスタンスを起動する想定です。
最後にイベント名などを設定します。
- 名前:StartEC2Instances と入力
- 説明:start EC2 instances every day at morning と入力
これで作業完了です。
確認
CloudWatch Eventsのログで確認することができます。
上記のいずれかをクリックすると各ストリームが出てくるので、最新の内容を見たい場合は時刻が最新のものをクリックします。
詳細画面を確認できます。下記の場合だと「START RequestId:xxxxxx」 でこのイベントがスタートしたことが記録されています。 次の行ではLambda Functionのコードで指定した内容が出力されていて、正常にLambdaが実行されたことが確認できます。
最後に
Lambdaは便利ですね。今回の手順はとても簡単なので是非活用してCost Efficiency にAWSを使っていきましょう!
以上です。