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

最終更新日: 2022 年 1 月 13 日

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

簡単な説明

注: この設定例は、簡単な解決策です。さらに確実な解決のためには、AWS Instance Scheduler を使用してください。詳細については、AWS Instance Scheduler を使用してインスタンスを停止および開始するにはどうすればよいですか? を参照してください。

Lambda を使用して、EC2 インスタンスを一定の間隔で停止および起動するには、次の手順を実行します。

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

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

3.    Lambda 関数のテスト

4.    関数をスケジュールどおりにトリガーする EventBridge ルールを作成します
注意: AWS アカウントで発生したイベントでトリガーするルールを作成することもできます

解決方法

注: 次の手順を完了した後に、起動時にクライアントエラーが表示される場合は、「暗号化されたボリュームがアタッチされた状態でインスタンスを起動すると、インスタンスは「起動時のクライアントエラー」というエラーで直ちに停止します」を参照してください。

停止して起動する EC2 インスタンスの ID を取得します。次に、以下を実行します。

Lambda 関数の 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 ロールを作成します

重要: アクセス許可ポリシーを Lambda にアタッチする場合は、必ずここで作成した IAM ポリシーを選択してください。

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

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

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

3.    [Basic information] に次の事項を追加します。
[Function name] に EC2 インスタンスを停止させる関数の名前を入力します。例えば「StopEC2Instances」のようになります。
[Runtime] (ランタイム) には [Python 3.9] を選択します。
[Permissions] (アクセス許可)で [Change default execution role (デフォルト実行ロールを変更)] を選択します。
[Execution role] (実行ルール) で [Use an existing role] (既存のロールを使用する) を選択します。
[Role] で今回作成した IAM ロールを選択します。

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

5.    [Code] (コード) の [Code source] (コードソース) で、次のコードをコピーして 、コードエディターのエディターペインに貼り付けます (lambda_function)。このコードは、指定したEC2 インスタンスを停止します。

関数コード例 - 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.stop_instances(InstanceIds=instances)
    print('stopped your instances: ' + str(instances))

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

6.    [Deploy] (デプロイ) を選択します。

7.    [Configuration] (構成) タブで、[General configuration] (一般構成)、[Edit] (編集) の順に選択します。[Timeout ] (タイムアウト) を 10 秒に設定し、[Save] (保存) を選択します。

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

8.    他にも関数が必要なときは、前出の 1~7 のステップを繰り返します。関数に EC2 インスタンスを起動させるには、前出の例を次のように変更します。

ステップ 3 で、以前に使用した関数名とは異なる関数名を入力します。例えば「StartEC2Instances」のようになります。
ステップ 5 で、コードエディター (lambda_function) のエディターペインに、次のコードをコピーして貼り付けます 。

関数コード例 - 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))

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

Lambda 関数のテスト

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

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

3.    [Code] (コード) タブを選択します。

4.    [Code source] (コードソース) セクションで [Test] (テスト) を選択します。

5.    [Configure test event] (テストイベントの設定) ダイアログボックスで、[Create new test event] (新しいテストイベントの作成) を選択します。

6.    イベント名を入力します。 その後、[Create] を選択します。

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

7.    [Test] (テスト) を選択して関数を実行します。

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

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

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

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

2.    [Create rule] (ルールを作成) を選択します。

3.    ルールの [Name] (名前) を入力します (「StopEC2Instances」など)。必要に応じて [Description] (説明) を入力できます。

4.    [Define pattern] (パターンを定義) で、[Schedule] (スケジュール) を選択します。

5.    次に、以下のいずれかを行います。

[Fixed rate of] に、分、時間、もしくは日の単位で時間間隔を入力します。
[Cron expression] に、Lambda にインスタンスを停止させる時刻を表すスケジュール式を入力します。式の構文に関する情報はルールのスケジュール式を参照してください。
注意
: Cron 式 は UTC で評価されます。適切なタイムゾーンに式を調整して使用してください。

6.    [Select targets] (ターゲットの選択) で、[Target] (ターゲット) ドロップダウンメニューから [Lambda function] (Lambda 関数) を選択します。

7.    [Function] (関数) で、EC2 インスタンスを停止させる関数を選択します。

8.    下にスクロールして [Create] (作成) を選択します。

9.    1~8 のステップを繰り返して、EC2 インスタンスを起動するためのルールを作成します。そのために、次の事項を変更して指定します。

ルールの名前を入力します (「StartEC2Instances」など)。
(オプション)「EC2 インスタンスを毎朝 7 時に開始する」などの説明を入力します。
ステップ 5 で、 [Cron expression] (Cron 式) には、インスタンスをいつ起動させるかを Lambda に指示する式を入力します。
ステップ 7 で、 [Function] (関数) には、EC2 インスタンスを起動する関数を選択します。

(オプション) AWS Instance Scheduler を使用して手順を自動化する

詳細については、「Automate starting and stopping AWS instances」を参照してください。