Lambdaを使って、EC2インスタンスを任意の時間で停止・起動してみる


この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。

Amazon EC2はAWSのコアサービスの一つですよね。そして、月の利用料金に占める割合も上位に入るサービスです

 

使った分だけ支払う従量課金制とはいえ、AWSの月額のコストを少しでも抑えたいと考える方は多いのではないでしょうか。そんな時はAWS LambdaとEvent Bridgeの利用を検討してみてください

 

週末はEC2インスタンスを停止していても問題ない、日中しかEC2インスタンスを使わない、という場合に有効な方法があります。

 

今回の記事ではEventBridgeでスケジュール設定をし、AWS Lambdaにトリガーすることで、任意の時間にEC2インスタンスの起動と停止を行う構築を紹介します。

 

 

Lambdaを使って、EC2インスタンスを任意の時間で停止・起動してみる

 

■構築の前に

lambda_stopstart_ec2

 

~構築の流れ~
今回の構築の流れは以下の順番です。
 

  • VPSなど作成
  • EC2作成
  • IAMロール&ポリシー作成
  • Lambda作成
  • EventBridge作成

 

 

それでは早速構築していきましょう。

 

 

■VPC作成

まずはVPCから作成していきます。わたしは今回シンガポールリージョンを使用しますが、任意のリージョンで作成してください。

 

VPC作成コンソールでサブネットやインターネットゲートウェイ、ルートテーブルが一気に作れます。

 

 

設定値は以下の通りです。

 

項目 設定値
作成するリソース VPCなど
名前タグの自動生成 saitou-handson(任意)
IPv4 CIDR ブロック 10.0.0.0/16
IPv6 CIDR ブロック IPv6 CIDR ブロックなし
アベイラビリティゾーン(AZ)の数 1
第1アベイラビリティゾーン ap-southeast-1a
パブリックサブネットの数 1
プライベートサブネットの数 0
1aのパブリックサブネットCIDR 10.0.1.0/24

 

 

lambda_stopstart_ec2

lambda_stopstart_ec2

lambda_stopstart_ec2

lambda_stopstart_ec2

 

 

■EC2インスタンス作成

次は起動・停止テスト用のEC2インスタンスの作成です。EC2インスタンスは起動と停止が実行されるか確認するだけなので、設定値はほぼデフォルトです。

 

 

設定値は以下の通りです。

 

 

項目 設定値
名前 saitou-handson-EC2(任意)
AMI Amazon Linux 2
アーキテクチャ 64ビットx86
インスタンスタイプ t2.micro
キーペア 任意
VPC saitou-handson-vpc
サブネット saitou-handson-subnet-public1
パブリック IP の自動割り当て 有効化
ファイアウォール セキュリティグループを作成する
セキュリティグループ名 saitou-handson-SG

 

 

EC2のダッシュボード画面から、「インスタンスを起動」をクリックしてください。

 

lambda_stopstart_ec2

lambda_stopstart_ec2

lambda_stopstart_ec2

lambda_stopstart_ec2

lambda_stopstart_ec2

lambda_stopstart_ec2

lambda_stopstart_ec2

lambda_stopstart_ec2

 

インスタンスの起動が正常に行われ、インスタンスIDが付与されました。インスタンスIDはLambda関数作成時に使用しますので、IDをメモ帳などにコピーしておいてください。

 

 

■IAMポリシー・ロール作成

続いて、AWS LambdaにアタッチするIAMロールとポリシーを作成します。まずはIAMポリシーから作成していきます。

 

 

IAMのダッシュボードの左ペインからポリシーをクリックし、「ポリシーを作成」をクリックしてください。

 

lambda_stopstart_ec2

 

↓JSONタブをクリックし、以下の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_stopstart_ec2

 

↓貼り付けが完了しましたら、右下の「次のステップ:タグ」を押してください。

 

lambda_stopstart_ec2

 

↓タグは任意で設定して、次のステップに進みましょう。

 

lambda_stopstart_ec2

lambda_stopstart_ec2

 

 

IAMポリシーの次は、IAMロールを作成いたします。

 

 

設定値は以下の通りです。

 

項目 設定値
信頼されたエンティティタイプ AWS のサービス
ユースケース Lambda
ロール名 saitou-StartStopEC2-IAMrole

 

 

IAMのダッシュボードの左ペインからロールをクリックし、「ロールを作成」を押してください。IAMロールについて詳しく知りたい方はこちらの記事を。

 

 

lambda_stopstart_ec2

lambda_stopstart_ec2

 

↓先ほど作成した許可ポリシーを検索し、チェックを付けて、「次へ」を押してください。

 

lambda_stopstart_ec2

lambda_stopstart_ec2

 

↓ロールを作成をクリックしてください。

 

lambda_stopstart_ec2

 

 

残りはLambda関数と、EventBridgeルールです。

 

 

■Lambda作成

まずはEC2インスタンスを停止させる関数を作成します

 

 

設定値は以下の通りです。

 

項目 設定値
関数の作成 一から作成
関数名 saitou-Lambda-StopEC2Instances
ランタイム Python 3.9
アーキテクチャ x86_64
実行ロール 既存のロールを使用する
既存のロール saitou-StartStopEC2-IAMrole

 

 

AWS Lambdaのダッシュボードから「関数の作成」をクリックしてください。

 

lambda_stopstart_ec2

lambda_stopstart_ec2

 

↓「関数の作成」をクリックしてください。

 

lambda_stopstart_ec2

 

 

↓コードタブ内にあるコードソースで、“lambda_function”ファイルに以下のコードを貼り付けます。※インスタンスIDやリージョンは該当の設定値に変更してください。

 

import boto3
region = '{リージョン名(ex:ap-southeast-1)}'
instances = ['{インスタンスID(id:i-xxxxxxxxxxxxxxxxxx)}']
ec2 = boto3.client('ec2', region_name=region)

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

 

シンガポールリージョンである私の場合は、以下のコードです。

 

import boto3
region = 'ap-southeast-1'
instances = ['i-094bbd9e922dc515d']
ec2 = boto3.client('ec2', region_name=region)

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

 

 

lambda_stopstart_ec2

 

↓コードを貼り付けましたら、「Deploy」を押してください。

 

lambda_stopstart_ec2

 

↓“関数saitou-test-StopEC2Instancesが正常に更新されました。”と出たら成功です。
 

lambda_stopstart_ec2

 

↓もう一点変更箇所がありますので、設定していきます。設定タブから一般設定を選び、編集をクリックしてください。

 

lambda_stopstart_ec2

 

↓基本設定のタイムアウトを10秒に変更し、保存してください。

 

lambda_stopstart_ec2

 

 

次に停止したEC2を起動させる関数を作成します。手順は一緒ですので、設定値だけ記述しておきます。

 

 

項目 設定値
関数の作成 一から作成
関数名 saitou-Lambda-StartEC2Instances
ランタイム Python 3.9
アーキテクチャ x86_64
実行ロール 既存のロールを使用する
既存のロール saitou-StartStopEC2-IAMrole

 

 

EC2を起動させるコードは以下のコードです。

 

import boto3
region = '{リージョン名(ex:ap-southeast-1)}'
instances = ['{インスタンスID(id:i-xxxxxxxxxxxxxxxxxx)}']
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    ec2.start_instances(InstanceIds=instances)
    print('started your instances: ' + str(instances))

 

例として、シンガーポールリージョンである私の場合は以下のコードです。

 

import boto3
region = 'ap-southeast-1'
instances = ['i-094bbd9e922dc515d']
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    ec2.start_instances(InstanceIds=instances)
    print('started your instances: ' + str(instances))

 

EC2を起動停止する関数の作成が完了しました。実際に起動停止できるかテストしてみましょう

 

 

■Lambda関数の動作テスト

作成したLambda関数が実際に動作するかテストしてみます。起動・停止テスト用のEC2インスタンスが実行中か確認してください。

 

 

lambda_stopstart_ec2

 

 

EC2インスタンスは起動していますね。まずは停止のテストを行います。

 

 

AWS Lambda関数から、作成した停止用Lambda関数(saitou-Lambda-StopEC2Instances)をクリックしてください。

 

lambda_stopstart_ec2

 

↓コードタブ内のコードソースから「Test」を押しましょう。

 

lambda_stopstart_ec2

 

↓テストイベント設定画面が出ましたら、イベント名を入力して「保存」をクリックしてください。イベント名は「saitou-StopEC2Instances」としました。

 

lambda_stopstart_ec2

 

↓“テストイベント saitou-StopEC2Instances は正常に保存されました。”と表示されましたら、コードタブ内のコードソースからもう一度「Test」を押してください。

 

lambda_stopstart_ec2

 

↓“Execution results”タブが表示されます。

 

lambda_stopstart_ec2

 

↓EC2のコンソール画面を見てみましょう。

 

lambda_stopstart_ec2

 

 

EC2インスタンスの停止が確認できました。

 

 

起動のテストもやってみましょう

 

AWS Lambda関数から起動関数(saitou-Lambda-StartEC2Instances)をクリックしてください。

 

lambda_stopstart_ec2

 

↓コードタブ内のコードソースから「Test」を押しましょう。

 

lambda_stopstart_ec2

 

↓テストイベント設定画面が出ましたら、イベント名を入力して「保存」をクリックしてください。イベント名は「saitou-StartEC2Instances」としました。

 

lambda_stopstart_ec2

 

↓“テストイベントsaitou-StartEC2Instancesは正常に保存されました。”と表示されましたら、コードタブ内のコードソースからもう一度「Test」を押してください。

 

lambda_stopstart_ec2

lambda_stopstart_ec2

 

↓“Execution results”タブが表示されます。

 

lambda_stopstart_ec2

 

↓EC2のコンソール画面を見てみましょう。

 

lambda_stopstart_ec2

 

 

EC2インスタンスの起動が確認できましたね。

 

AWS Lambda関数を使用してEC2インスタンスの起動と停止の実行が確認できました。

 

最後にEventBridgeルールを作成して、任意の時間に起動と停止が行えるようにします。

 

 

■EventBridgeルール作成

Amazon EventBridgeを利用して、まずは停止用のルールを作成します。

 

 

設定値は以下の通りです。

 

項目 設定値
名前 saitou-StopEC2Instances
イベントバス default
ルールタイプ スケジュール
スケジュールパターン 特定の時刻
Cron 式 任意
ターゲットタイプ AWS のサービス
ターゲットを選択 Lambda関数
機能 saitou-Lambda-StopEC2Instances

 

 

EventBridgeのコンソール画面から、「ルールを作成」をクリックしてください。

 

lambda_stopstart_ec2

 

 

lambda_stopstart_ec2

 

↓ルールタイプはスケジュールを選択し、次へをクリックしてください。

 

lambda_stopstart_ec2

 

 

↓スケジュールパターンは、特定時刻を選択し、毎日特定の時間に停止するようにスケジュールします。cron式の例は以下の通りです。詳しくはAmazon公式ドキュメントで確認ください。日本はUTC+9です。

 

 

状況
毎日午前 10:15 (UTC) cron(15 10 ? *)
毎週月曜日から金曜日まで午後 6:00 cron(0 18 ? MON-FRI )
毎月 1 日の午前 8:00 cron(0 8 1 ? )
平日の 10 分ごと cron(0/10 ? MON-FRI *)
月曜日から金曜日まで午前 8:00 から午後 5:55 まで 5 分ごと cron(0/5 8-17 ? MON-FRI )
毎月最初の月曜日の午前 9 時 cron(0 9 ? 2#1 )

 

 

わたしは今回構築テストをする関係で、今から20分後の時間を指定しました。

 

cron(30 7 * * ? *) #「毎日16:30」を指定しました

 

lambda_stopstart_ec2

lambda_stopstart_ec2

 

↓確認画面で設定に問題なければ、作成を押してください。

 

lambda_stopstart_ec2

 

 

起動用のルールも作成しましょう。設定値は以下の通りです。

 

項目 設定値
名前 saitou-StartEC2Instances
イベントバス default
ルールタイプ スケジュール
スケジュールパターン 特定の時刻
Cron 式 任意
ターゲットタイプ AWS のサービス
ターゲットを選択 Lambda関数
機能 saitou-Lambda-StartEC2Instances

 

 

ルールタイプはスケジュールを選択し、次へをクリックしてください。

 

lambda_stopstart_ec2

 

↓スケジュールパターンは、特定時刻を選択し、毎日特定の時間に停止するようにスケジュールします。私は毎日16:40にトリガーするように設定しました。

 

cron(40 7 * * ? *) #「毎日16:40」を指定しました

 

lambda_stopstart_ec2

 

↓ターゲットタイプは“AWSのサービス”、ターゲットを“Lambda関数”を選択してください。機能はEC2インスタンス起動用のLambda関数を選択します。

 

lambda_stopstart_ec2

 

さいごに確認画面が表示されます。設定に問題なければ、「作成」を押してください。

 

 

構築は以上です。

 

 

■動作確認

EventBridgeのルールで、毎日16:30にLambda関数(StopEC2Instances)にトリガーし、毎日16:40にLambda関数(StartEC2Instances)にトリガーするように設定しました。

 

16:30になったので、EC2インスタンスを見てみましょう。

 

lambda_stopstart_ec2

 

しっかりと停止していますね。

 

10分後の16:40にEventBridgeがLambdaにトリガーし、EC2インスタンスが起動するか待ちましょう。

 

lambda_stopstart_ec2

 

起動には数分かかりますので、16:41に実行になりました。

 

 

まとめ:Lambdaを使って、EC2インスタンスを任意の時間で停止・起動してみる

AWS LambdaやAmazon EventBridgeを利用することで、不要なコストを削減できます。また、EC2の停止を自動化しておくことで、停止忘れも防げますよね。ぜひ試してみてください。

 

 

参考リンク:AWS ナレッジセンター

 

 

↓ほかの協栄情報メンバーもAWS Lambdaに関する記事を公開しています。ぜひ参考にしてみてください。

 

■LambdaによるEC2のステータスチェックの構築(INAMURA)
https://cloud5.jp/ec2statuschecks_with_lambda/

 

■Lambdaから別アカウントのS3にアクセスしてみました。(小林 剛)
https://cloud5.jp/access-s3-of-another-account-from-lambda/

 

■AWS Lambdaを利用したLINEbotハンズオン(INAMURA)
https://cloud5.jp/aws-lambda_line-api/

 

Last modified: 2023-10-28

Author