AWS Lambdaでインスタンスの起動・停止バッチ


開発用インスタンスの停止忘れを防止したい

使用頻度が低い開発サーバを必要に応じて手動で起動と停止を行ってきましたが、停止を忘れてしまうことなどが発生してきたので、下記の公式記事を参考にAWS Lambdaでバッチ化することにしました。

Lambda を使用して、Amazon EC2 インスタンスを一定の間隔で停止および起動するにはどうすればよいですか?

今回実施する内容の流れ

  1. IAMポリシー、Lambda実行用ロールを作成します。

  2. LambdaでEC2インスタンス停止関数を作成します。

  3. スケジュールに合わせて実行するよう、CloudWatch Events のルールを作成します。

1. IAMポリシー、IAMロール作成

まずは上記で紹介している通り、起動停止用のポリシーを作成します。

IAMポリシーの作成

下記は公式に掲載されているポリシーのJSONコードを元にしています。
私の場合はEC2のステータス取得権限とRDSの起動・停止権限も追加しました。

{
    "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*",
                "ec2:describe*",
                "rds:Start*",
                "rds:Stop*"
            ],
            "Resource": "*"
        }
    ]
}

ポリシーの作成を押せば完了です。

IAMロールの作成

2. LambdaでEC2インスタンス停止関数作成

今回はEC2の停止を行う関数サンプルです。
EC2を起動したい場合はec2.startに変更するだけです。
下記は2台のEC2を停止するサンプルで、必要に応じてインスタンスIDで指定します。


import boto3
region = 'ap-northeast-1'
instances = ['i-XXXXXXXXXXXXXXXXX', 'i-XXXXXXXXXXXXXXXXX']
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    ec2.stop_instances(InstanceIds=instances) # ← ec2.startに変更すると起動
    print('stopped your instances: ' + str(instances))

Lambda関数のテスト

公式を見ていてもここがよくわからなかったのですが、Lambda関数をテスト実行する前に「テストイベントの作成」を求められます。

テストをクリック

テストイベントの内容

これで再度テストを行うと、Lambdaが実行され結果が返されます。

3. CloudWatchEventsでスケジュール実行

※Cron式の詳しい内容は下記を参照ください
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/tutorial-scheduled-events-schedule-expressions.html

続き

以上で設定は完了です。

指定した時間にEC2が停止されることが確認してください。