Lambda を使用して Amazon EC2 インスタンスを定期的に停止および起動する方法を教えてください。

最終更新日: 2019 年 6 月 28 日

自動的に EC2 インスタンスを停止および起動することで、Amazon Elastic Compute Cloud (Amazon EC2) の使用量を削減したいと考えています。AWS Lambda と Amazon CloudWatch Events を使用して、それを行うにはどうすればよいですか?

簡単な説明

注: この設定例は、簡単な解決策です。より堅実な解決策については、AWS インスタンススケジューラを使用してください

このセットアップでは、次のタスクを実行してください。

1.    カスタム AWS Identity and Access Management (IAM) ポリシーと Lambda 関数の実行ロールを作成します。

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

3.    CloudWatch Events ルールを作成し、関数をスケジュールに従ってトリガーします。たとえば、夜間に 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] では、[Python2.7] を選択します。
[Permissions] で、[Choose or create an execution role] をします。
[Execution role] で、[Use an existing role] を選択します。
[Existing 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']

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

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

注: ユースケースで必要に応じて、Lambda 関数を設定します。たとえば、複数のインスタンスを停止してから起動する場合は、[Memory] だけでなく、[Timeout] で異なる値が必要な場合があります。

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

8.    ステップ 1 から 7 を繰り返して、別の関数を作成します。この関数で EC2 インスタンスを起動させるには、次のようにします。
ステップ 3 では、EC2 インスタンスを起動する関数として、[Function name] を入力します。たとえば、「StartEC2Instances」です。
ステップ 5 では、次のコードをコピーして、コードエディタのエディタペインに貼り付けます (lambda_function)。

注:[region] および [instances] では、EC2 インスタンスを停止するコードで使用したのと同じ値を使用します。

import boto3
region = 'us-west-1'
instances = ['i-12345cb6de4f78g9h', 'i-08ce9b2d7eccf6d26']

def lambda_handler(event, context):
    ec2 = boto3.client('ec2', region_name=region)
    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] には、ルールの説明を記入します。たとえば、「毎晩午後 10 時に EC2 インスタンスを停止する」とします。
[State] では、[Enabled] チェックボックスを選択します。

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

12.    ステップ 1~11 を繰り返して、EC2 インスタンスを起動するためのルールを作成します。以下の異なる手順を実行します。
ステップ 5 で、[Cron expression] には、インスタンスをいつ起動するかを Lambda に指示する式を入力します。
ステップ 8 で、[Function] には、EC2 インスタンスを起動する関数を選択します。
ステップ 10 で、[Rule definition] には、「StartEC2Instances」のように [Name] を入力し、必要に応じて、「毎朝午前 6 時に EC2 インスタンスを起動する」のように [Description] を入力します。