この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。
はじめに
こんにちは、これからブログの形でAWS利用と知識に関する様々な情報を公開していきたいと思います。AWSを使用する時、コストを控えたり、手間を省いたり場合には自動でインスタンスを起動・停止したい時があります。今回は「一つのLambdaで定期的に複数のEC2インスタンスを起動・停止させる方法」を紹介していきます。ちなみに、対象が複数インスタンスでも可能です。
概要
必要なサービスは、以下の2つです。
サービス | 機能 |
---|---|
CloudWatch events | Lambdaを呼び出すトリガー用 |
Lambda | インスタンスを起動・停止させる関数を実行 |
IAM | 権限を提供する |
手順としては大まかな流れは下記の3つになります。
- IAMポリシーとIAMロールの作成
- Lambda関数の作成
- CloudWatchのイベントの作成
IAMポリシーとロールの作成
IAMポリシーの作成
EC2 instancesの起動・停止を実行できるポリシーを作ります。実行ログをCloudWatchに出力したかったので、logsのポリシーも付与しています。ポリシー名はstartstop-ec2をつけます。
ポリシー内容は以下です。
{
"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が実行できるようにIAM Roleを割り当てます。信頼されたエンティティはLambdaを選択し先ほど作成したstartstop-ec2というポリシーをアタッチして作成します。
設定は完了したら、以下の画面になります。
各項目の設定は以下に設定しました。
項目 | 設定内容 |
---|---|
信頼されたエンティティ | Lambda |
アタッチするポリシー | startstop-ec2 (先ほど作成したポリシー) |
ロール名 | startstop-ec2-role (入力任意) |
Lambda Functionの作成
Lambdaの画面を開いて関数の作成をクリックします。
各項目の設定は以下に設定しました。
項目 | 設定内容 |
---|---|
関数名 | startstop-ec2-lambda (入力任意) |
ランタイム | pyhton 3.8 |
実行ロール | startstop-ec2 (先ほど作成したロール) |
ソースコードは以下に記述しました。
import boto3
def lambda_handler(event, context):
region = event['Region']
instances = event['Instances']
ec2 = boto3.client('ec2', region_name=region)
if event['Action'] == 'start':
ec2.start_instances(InstanceIds=instances)
elif event['Action'] == 'stop':
ec2.stop_instances(InstanceIds=instances)
else:
return 1
return 0
- region = event[‘Region’]はイベントに渡されたリージョンを定義します。
- instances = event[‘Instances’]はイベントに渡されたインスタンスを定義します。
- ec2.start_instances(InstanceIds=instances)はインスタンスを起動することを定義します。
- ec2.stop_instances(InstanceIds=instances)はインスタンスを停止することを定義します。
ここのコードでは、特定のリージョン、インスタンスを入力することは不要です。
CloudWatch Events で起動・停止のイベントスケジュールを作成
イベントの選択
各項目の設定は以下に設定しました。
項目 | 設定内容 |
---|---|
イベントバターン | スケジュール |
Cron式の入力 | 0 5 ? * MON-FRI * |
このCron式の設定の意味は、平日日本時間の14時という意味になります。注意する点はcron式で指定する時間はUTC timeですので、UTCとJTCの時間差を注意して設定してください。
ターゲットの入力
各項目の設定は以下に設定しました。
項目 | 設定内容 |
---|---|
ターゲット | Lambda関数 |
関数 | startstop-ec2-lambda (先ほど作成した関数) |
ターゲットへの入力(JSON文字列)は以下の通りです。
{"Action": "stop","Region":"ap-northeast-1","Instances": ["i-xxxxxxxxxxxxxxxxx","i-xxxxxxxxxxxxxxxxx""]}
このように設定すれば、東京リージョンでの選定されたインスタンスidのインスタンスが自動停止を実行できます。起動する場合は、JSON文字列は{"Action": "start","Region":"ap-northeast-1","Instances": ["i-xxxxxxxxxxxxxxxxx","i-xxxxxxxxxxxxxxxxx""]}とすれば実行できます。
操作したいリージョンとインスタンスのIDを環境に合わせて入れ替えられます。
テスト確認
上記の流れはすべて終わってから、一度テストしましょう。CloudWatch Eventsのロググループでテストの結果を確認できます。
上記をクリックすると、ストリームの内容が出てきました。
上記の画面だと「START RequestID」でこのイベントの開始を記録されています。「END RequestID」でイベントの終了を記録されています。何もエラーメッセージが出ないので、無事にLambdaが実行されたことが確認できます。
まとめ
このように設定すると、自動起動・停止の対象にしたいインスタンスが増えても管理しやすいです。
1時間もあれば設定できるので、是非やってみてください。