この記事について
LambdaとEventBridgeを利用してEC2インスタンスの自動開始・自動停止を設定してみました。
EventBridgeを使用すれば簡単に設定することが可能です。
毎月のAWSのEC2料金が節約できるかも。。
前提条件
起動中のEC2インスタンスがあること。
Lambda用のIAMポリシーとIAMロールの作成
IAMのコンソール画面に移動し、「ポリシーを作成」をクリック。
名前を入力し、「ポリシーの作成」をクリック。
今回は「EC2StartStop」とします。
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": "*"
}
]
}
IAMポリシーが作成されました。
(タグは特に何も設定せず作成しました。)
次にロールを作成します。
サイドバーからロールを選択し、「ロールを作成」をクリック。
「AWSのサービス」、ユースケースは「Lambda」を選択し、次へ。
ロール名は「EC2StartStop-Role」として、次へ。
許可ポリシーで先ほど作成した、「EC2StartStop」ポリシーにチェックして、次へ。
LambdaからEC2にアクセスするための、IAMロールが作成されました。
Lambda関数の作成
起動用と停止用の2つのLambda関数を作成します。
Lambdaコンソールに移動し、「関数の作成」をクリック。
関数名は「StopEC2Instance」とし、ランタイムは「Python3.9」を選択。
実行ロール「既存のロールを使用する」を選択し、先ほど作成した「EC2StartStop-Role」を選択。
下記コードを貼り付け、「Deploy」をクリック。
インスタンスIDはEC2のコンソール画面からコピーしてきます。
※instances = ['<インスタンスID>,<インスタンスID>,<インスタンスID> ']
とすれば複数まとめて起動・停止処理可能です。
import boto3
region = '<リージョン名>'
instances = ['<インスタンスID>']
ec2 = boto3.client('ec2', region_name=region)
def lambda_handler(event, context):
ec2.stop_instances(InstanceIds=instances)
print('stopped your instances: ' + str(instances))
停止できるかどうかテストしてみます。
デフォルトそのままでいいのでテストイベントを作成し、「Test」をクリック。
↓テスト実行後の画面。
EC2のコンソールに移動し、停止していることを確認します。
同じ方法で起動するためのLambda関数も作成します。
上記と同じ方法でPython3.9の関数を作成、関数名は「StartEC2Instance」としました。
import boto3
region = '<リージョン名>'
instances = ['<インスタンスID>']
ec2 = boto3.client('ec2', region_name=region)
def lambda_handler(event, context):
ec2.start_instances(InstanceIds=instances)
print('started your instances: ' + str(instances))
同じ要領でテストしてみます。
EC2が実行中になりました。
作成した2つの関数は実行中に処理が中断しないようにタイムアウトを10秒にしておきます。
Lambda関数画面 > 「設定」タブ > サイドバー「一般設定」 > 編集から設定します。
※この記事下部の参考リンクにも記載があります
EventBridgeの設定
EC2の自動起動停止の時間を設定するためのルールをEventBridgeで作成します。こちらも停止用と起動用で2つのルールを作成します。
EventBridgeのコンソールに移動し、「ルールを作成」をクリック。
名前は「StopEC2Instance」とします。
ルールタイプは「スケジュール」を選択して、次へ。
スケジュールパターン「特定の時刻」を選択。
Cron式で希望の時間を設定します。今回は毎日22時に停止してほしいため、下記のように設定し、次へ。
0 13 * * ? *
ターゲットタイプは「AWSのサービス」を選択。
ターゲットで「Lambda関数」を選択し、作成した「StopEC2Instance」を選択し、次へ。
タグは特に設定せずに次へ。
設定内容に問題がなければ、「ルールの作成」クリック。
ルールが作成されました。
同じ要領で「ルールの作成」をクリックして起動用のルールも作成します。
名前「StartEC2Instance」、ルールタイプ「スケジュール」を選択して次へ。
スケジュールパターン「特定の時刻」を選択。
Cron式で希望の時間を設定します。毎日7時に起動してほしいため、下記のように設定し、次へ。
0 22 * * ? *
ターゲットタイプ「AWSのサービス」を選択。
ターゲットで「Lambda関数」を選択し、作成した「StartEC2Instance」を選択し、次へ。
タグは特に設定せずに次へ。
設定内容に特に問題がなければ「ルールの作成」をクリック。
停止と起動の2つのルールが作成されました!
あとは時間通りに停止・起動しているかを、設定した時間経過後にEC2のコンソール画面でチェックを行います。(今回の設定内容だと毎朝7時と22時)
問題なく停止、起動していれば成功です!!
CloudWatchに出力されたログを確認
設定した時間経過後にEC2コンソールを直接見に行って停止・起動しているかも確認できますが、CloudWatchに出力されたログも確認してみます。
作成したLambda関数の「モニタリング」タブ > 「CloudWatchのログを表示」をクリック。
CloudWatchのコンソールが開きます。
ログストリームの中に指定した時間のログができていることを確認してクリック。
Lambdaソースの中で出力している内容が確認できました。
※ログが出力されているのにEC2が停止または起動していない場合は、インスタンスIDやリージョンが間違ってないかなどを確認します
参考リンク
この記事で使用したポリシーのJSON、Lambda関数などは下記の記事の内容をコピーして使用しています。
コメント