こんにちは。ソリューション技術部の栗原です。
弊社では社内で開発環境にAWSのEC2を利用しています。 EC2インスタンスは従量課金なのでなるべく必要なときだけ起動しておくようにしたいですが、 毎回コンソールにログインして起動や停止をするのは意外と面倒ですし、停止し忘れると使用していない間も課金されてしまうので AWS LambdaとCloudWatch Eventsを利用してEC2インスタンスの起動、停止を自動化する仕組みを取り入れました。
今回はその設定方法についてご紹介したいと思います。
方針
設定方法
EC2インスタンスのタグ付け
まず、EC2インスタンスにタグを付けます。
起動させるインスタンスにはstartタグを、停止させるインスタンスにはstopタグを付け、値に時刻をJSTで設定します。
3台のEC2インスタンスに、以下のように設定しました。

Lambda用IAMロールの作成
次に、Lambdaが使用するIAMロールを作成します。
IAMコンソールを開き、[ロールの作成]を選択します。

以下のように選択し、[次のステップ:アクセス権限]を選択します。

アタッチするポリシーとして「AmazonEC2ReadOnlyAccess」を選択し、[次のステップ:確認]を選択します。

ロール名に任意の名前を入力後、[ロールの作成]を選択し、IAMロールを作成します。

さらに、インラインポリシーを追加します。
先ほど作成したIAMロールの詳細画面を開き、[インラインポリシーの追加]を選択します。

以下のポリシーを設定し、ポリシーを作成します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"ec2:StartInstances",
"ec2:StopInstances"
],
"Resource": "*"
}
]
}
インラインポリシーが追加されました。

これでIAMロールの作成は完了です。
Lambda関数の作成
最後に、Lambda関数を作成します。
Lambdaコンソールを開き、[関数の作成]を選択します。

以下の値を入力して[関数の作成]を選択し、Lambda関数を作成します。

これでLambda関数が作成できました。残りの設定をしていきます。
関数コード
Lambda実行時刻(12時に実行された場合は12)が startタグもしくはstopタグの値に設定されているEC2インスタンスを抽出し、起動停止します。
from datetime import datetime import boto3 def lambda_handler(event, context): now_hour = datetime.now().strftime('%H') ec2 = boto3.resource('ec2') start_instances = ec2.instances.filter( Filters=[ { 'Name': 'tag:start', 'Values': [ now_hour, ], }, { 'Name': 'instance-state-name', 'Values': [ 'stopped', ], }, ], ) stop_instances = ec2.instances.filter( Filters=[ { 'Name': 'tag:stop', 'Values': [ now_hour, ], }, { 'Name': 'instance-state-name', 'Values': [ 'running', ], }, ], ) for i1 in start_instances: i1.start() print('start: ' + i1.instance_id) for i2 in stop_instances: i2.stop() print('stop: ' + i2.instance_id)
環境変数
EC2インスタンスのタグに時刻をJSTで設定していますので、
以下のように設定し、LambdaのタイムゾーンもUTCからJSTに変更します。

タイムアウト
処理がタイムアウトしないように1分に変更します。

トリガー
トリガーにCloudWatch Eventsを選択し、追加します。

ルールタイプは「スケジュール式」を選択し、以下の値を入力します。
cron(0 * ? * MON-FRI *)
月曜日から金曜日の毎時0分(UTC)にLambdaが実行されます。
[追加]を選択してルールを作成します。

これで設定はすべて完了です。
動作確認
13時前はこの状態。

13時を過ぎるとLambdaが実行され、demo01が起動、demo02が停止しました。
期待通りの動きですね。
最後に
EC2インスタンスの起動、停止を自動化することができました。 Lambdaを使って自動化できることが他にもいろいろとありそうです。