Amazon EC2 の使用量を減らすために、Amazon Elastic Compute Cloud (Amazon EC2) インスタンスを自動的に停止し、起動したいです。
簡単な説明
AWS Lambda と Amazon EventBridge を使用すると、EC2 インスタンスを自動的に停止、起動することができます。
注: 以下に示す解決方法はシンプルなソリューションの例です。より高度なソリューションでは、AWS Instance Scheduler を使用してください。詳細については、「AWS インスタンスの起動と停止を自動化する」を参照してください。
Lambda を使用して EC2 インスタンスを定期的に停止したり起動したりするには、次の手順を実行します。
- Lambda 関数用のカスタム AWS Identity and Access Management (IAM) ポリシーと IAM ロールを作成します。
- EC2 インスタンスの停止と起動をする Lambda 関数を作成します。
- Lambda 関数をテストします。
- スケジュールに従って関数を実行する EventBridge スケジュールを作成します。
Lambda 関数でインスタンスが停止した後、再起動できない場合があります。これは、Amazon Elastic Block Store (Amazon EBS) ボリュームが暗号化されていて、Lambda ロールにその暗号化キーを使用するアクセス許可がない場合に発生する可能性があります。詳細については、「暗号化されたボリュームで使用するために必要な AWS KMS キーポリシー」を参照してください。
解決策
前提条件: 停止と起動をする EC2 インスタンスの ID を取得します。
Lambda 関数の IAM ポリシーと IAM ロールを作成する
次の手順を実行します。
-
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": "*"
}
]
}
-
Lambda 用の IAM ロールを作成します。
-
IAM ポリシーを IAM ロールにアタッチします。
注: Amazon Elastic Block Store (Amazon EBS) ボリュームを使用する場合、追加の設定が必要になる場合があります。Amazon EBS ボリュームがカスタマーマネージド AWS Key Management Service (AWS KMS) キーで暗号化されている場合は、kms:CreateGrant を IAM ポリシーに追加します。
インスタンスの停止と起動をする Lambda 関数を作成する
次の手順を実行します。
-
Lambda コンソールを開き、[関数の作成] を選択します。
-
[一から作成] を選択します。
-
[基本的な情報] に、次の情報を入力します:
[関数名] には、StopEC2Instances や StartEC2Instances など、その関数を説明する名前を入力します。
[ランタイム] で、[Python 3.9] を選択します。
[アクセス許可] で、[デフォルトの実行ロールの変更] を展開します。
[実行ルール] で [既存のロールを使用する] を選択します。
[実行ロール] で、IAM ロールを選択します。
-
[関数の作成] を選択します。
-
[コード] タブを選択します。
-
[コードソース] の [lambda_funciton.py] タブで、コードエディタに次のコードを入力し、stop_instances を行います。
import boto3region = '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))
start_instances を行うには、コードエディタに次のコードを入力します。
import boto3region = '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))
注: us-west-1 はお使いのインスタンスがある AWS リージョンに、InstanceIds は停止、起動させるインスタンスの ID に置き換えます。
-
[デプロイ] を選択します。
-
[Configuration] タブで [General configuration] を選択し、[Edit] を選択します。
-
[タイムアウト] を 10 秒に設定し、[保存] を選択します。
Lambda 関数をテストする
次の手順を実行します。
- Lambda コンソールを開き、[関数] を選択します。
- 作成した関数の 1 つを選択します。
- [Code] タブを選択します。
- [Code source] セクションで、[Test] を選択します。
- [テストイベントの設定] ダイアログボックスで、[新しいテストイベントの作成] を選択します。
- イベント名を入力し、[作成] を選択します。
注: テストイベントの JSON コードは変更しないでください。
- [テスト] を選択して関数を実行します。
- 他の関数についても、手順 1 ~ 7 を繰り返します。
インスタンスのステータスを確認する
Amazon EC2 コンソール
テストの前後にインスタンスのステータスをチェックし、関数が動作することを確認します。
CloudTrail
AWS CloudTrail を使用してイベントをチェックし、Lambda 関数でインスタンスが停止または起動したかを確認することもできます。
次の手順を実行します。
- CloudTrail コンソールを開きます。
- ナビゲーションペインで [イベント履歴] を選択します。
- [ルックアップ属性] ドロップダウンリストで、[イベント名] を選択します。
- 検索バーにStopInstances と入力して結果を確認します。次に、StartInstances と入力します。
結果が表示されない場合は、Lambda 関数によりインスタンスが停止または起動が行われていません。
Lambda 関数を実行する EventBridge ルールを作成する
次の手順を実行します。
- EventBridge コンソールを開きます。
- [ルールを作成] を選択します。
- StopEC2Instances や StartEC2Instances など、ルールの名前を入力します。
- (オプション) [説明] に、ルールの説明を入力します。
- [ルールタイプ] で [スケジュール] を選択し、[EventBridge Scheduler で続行] を選択します。
- [スケジュールパターン] の [頻度] で、[繰り返しのスケジュール] を選択します。
- [スケジュールタイプ] で [レートベースのスケジュール] または [cron ベースのスケジュール] を選択し、次のいずれかの手順を実行します。
[レートベースのスケジュール] では、レート値を入力し、時間間隔 (分、時間、または日) を選択します。
または、
[Cron ベースのスケジュール] では、インスタンスを停止または起動させるタイミングを Lambda に指示する式を入力します。
注: cron 式は UTC で評価されます。該当するタイムゾーンに合わせて式を調整してください。
- [ターゲットの選択] ページで、[ターゲット] ドロップダウンリストから [Lambda 関数] を選択します。
- [関数] で、インスタンスを停止または起動させる関数を選択します。
- [スキップして確認、作成] を選択し、[作成] を選択します。
注: AWS アカウントのイベントに対応するルールを作成することもできます。
関連情報
チュートリアル: AWS Lambda 関数用の EventBridge スケジュールルールを作成する
EventBridge での AWS サービスからのイベント
Amazon EC2 の請求および購入オプション