Lambda を使用して、Amazon EC2 インスタンスを一定の間隔で停止および起動するにはどうすればよいですか?
最終更新日: 2020 年 10 月 21 日
簡単な説明
注: この設定例は、簡単な解決策です。さらに確実な解決には AWS Instance Scheduler を使用してください。詳細については、AWS Instance Scheduler を使用してインスタンスを停止および開始する方法を教えてくださいをご参照ください。
このセットアップでは、次のタスクを実行してください。
1. AWS Identity and Access Management (IAM) ポリシー、および Lambda 関数実行のためのロールを作成します。
2. Lambda 関数を、EC2 インスタンスを停止および起動するように作成します。
3. スケジュールに合わせこの関数をトリガーするよう、CloudWatch Events のルールを作成します。たとえば、1 つのルールで EC2 インスタンスを夜に停止させ、別のルールで朝に再起動させます。
解決方法
停止および起動したい 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. AWS 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 関数の定義を行います。たとえば、複数のインスタンスを停止および起動したい場合は、Timeout や Memory には違う値が必要になることがあります。
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. AWS 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. Amazon 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 で、[ルールの定義] には、「StartEC2Instances」のように [名前] を入力し、必要に応じて、「毎朝午前 6 時に EC2 インスタンスを起動する」のように [説明] を入力します。