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

最終更新日: 2019 年 8 月 30 日

EC2 インスタンスを自動的にで停止および起動することで、Amazon Elastic Compute Cloud (Amazon EC2) の使用量を削減したいと考えています。そのための、AWS Lambda と Amazon CloudWatch Events の使い方を教えてください。

簡単な説明

注: ここでご紹介するソリューションは簡素化したものです。さらに確実な解決には AWS Instance Scheduler を使用してください。

この解決には次のことを行います。

1.    AWS Identity and Access Management (IAM) ポリシー、および Lambda 関数実行のためのロールを作成します。

2.    Lambda 関数を、EC2 インスタンスを停止および起動するように作成します。

3.    スケジュールに合わせこの関数をトリガーするよう、CloudWatch Events のルールを作成します。たとえば、1 つのルールで EC2 インスタンスを夜に停止させ、別のルールで朝に再起動させます。

注: また、AWS アカウントで発生するイベントがトリガーするよう、ルールを作成することもできます

解決方法

停止および起動をしたい EC2 インスタンスの ID を取得した後、次の指示に従います。

IAM ポリシーとロールを作成する

1.    JSON ポリシーエディターを使い IAM ポリシーを作成します。ポリシーエディターに、次に示す JSON 形式のポリシー設定をコピーしてください。

{
  "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": "*"
    }
  ]
}

2.    Lambda のための IAM ロールを作成する。アクセス許可ポリシーをアタッチする際は、ここで作成した IAM ポリシーを検索および適用します。

EC2 インスタンスを停止および起動する Lambda 関数を記述する

1.    Lambda コンソールで、[Create function] クリックします。

2.    [Author from scratch] をクリックします。

3.    [Basic information] に次の事項を追加します。
[Function name] に EC2 インスタンスを停止させる関数の名前を入力します。たとえば「StopEC2Instances」のようになります。
[Runtime] で [Python 3.7] を選択します。
[Permissions] で [Choose or create an execution role] を展開します。
[Execution role] で [Use an existing role] を選択します。
[Role] で今回作成した IAM ロールを選択します。

4.    [Create function] をクリックします。

5.    次のコードをコピーし、[Function code] の中にあるコードエディターのエディターペインにペーストします (lambda_function) 。このコードでは指定したEC2 インスタンスを停止します。

注: region の項にある「us-west-1」は、ご自身のインスタンスがある AWS リージョンと置き換えます。また、instances の項にあるサンプルの EC2 インスタンス ID は、実際に停止および起動したいものの ID と置き換えます。

import boto3
region = 'us-west-1'
instances = ['i-12345cb6de4f78g9h', 'i-08ce9b2d7eccf6d26']
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    ec2.stop_instances(InstanceIds=instances)
    print('stopped your instances: ' + str(instances))

6.    [Basic settings] の [Timeout] に 10 秒を設定します。

注: ご自身のユースケースに合わせ、Lambda 関数の定義を行います。たとえば、複数のインスタンスを停止および起動したい場合は、TimeoutMemory には違う値が必要になることがあります。

7.    [Save] を選択します。

8.    他にも関数が必要なときは、前出の 1~7 のステップを繰り返します。関数に EC2 インスタンスを起動させるには、前出の例を次のように変更します。
ステップ 3 での [Function name] に、 EC2 インスタンスを起動させる関数名を入力します。たとえば「StartEC2Instances」のようになります。
ステップ 5 でのコードエディター (lambda_function) 上のエディターペインには、次のコードをコピーします 。

注: region および instances の値には、EC2 インスタンスを停止させた関数と同じものを記述します。

import boto3
region = 'us-west-1'
instances = ['i-12345cb6de4f78g9h', 'i-08ce9b2d7eccf6d26']
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    ec2.start_instances(InstanceIds=instances)
    print('started your instances: ' + str(instances))

Lambda 関数のテスト

1.    Lambda コンソールで、[Functions] をクリックします。

2.    先に作成した関数から 1 つ選択します。

3.    [Actions]、[Test] の順にクリックします。

4.    [Configure test event] ダイアログで、 [Create new test event] をクリックします。

5.    [Event name] を入力した後、 [Create] をクリックします。.

注: 今回の関数では使用しないため、このテストに使うイベントに関する JSON を修正する必要はありません。

6.    [Test] をクリックし関数を実行します。

7.    先に作成した関数で行った、1~6 のステップを繰り返します。

ヒント: 作成した関数が希望通りに動作するかのテストの前後で、EC2 インスタンスの状態をチェックします。

Lambda 関数をトリガーするルールを作成する

1.    CloudWatch コンソールを開きます。

2.    左のナビゲーションペインにある [Events] で、 [Rules] をクリックします。

3.    [Create rule] を選択します。

4.    [Event Source] の [Schedule] をクリックします。

5.    次に、以下のいずれかを行います。
[Fixed rate of] に、分、時間、もしくは日の単位で時間間隔を入力します。
[Cron expression] に、Lambda にインスタンスを停止させる時刻を表すスケジュール式を入力します。スケジュール式の書式に関する情報は「ルールのスケジュール式」をご参照ください。
注: Cron スケジュール式 は UTC で評価されます。ご自身に合ったタイムゾーンにスケジュール式を調整してご使用ください。

6.    [Targets] の [Add target] をクリックします。

7.    [Lambda function] をクリックします。

8.    [Function] から EC2 インスタンスを停止させる関数を選択します。

9.    [Configure details] を選択します。

10.    [Rule definition] で次の事項を行います。
[Name] には「StopEC2Instances」といったようなルールを指定する名称を入力します。
(任意) [Description] でルールを記述します。たとえば「Stops EC2 instances every night at 10 PM.」のようになります。
[State] で [Enabled] チェックボックスをオンにします。

11.    [Create rule] をクリックします。

12.    1~11 のステップを繰り返し EC2 インスタンスを起動するためのルールを作成します。そのために、次の事項を変更して指定します。
ステップ 5 での [Cron expression] には、 Lambda にインスタンスを起動させる時刻を表すスケジュール式を入力します。
ステップ 8 での [Function] では、EC2 インスタンスを起動する関数名を選択します。
ステップ 10 での [Rule definition] では [Name] に「StartEC2Instances」のように入力し、必要な場合は [Description] に「Starts EC2 instances every morning at 6 AM.」のように入力します。