紙一重の積み重ね

35歳のエンジニアがなれる最高の自分を目指して、学んだことをこつこつ情報発信するブログです。

AWS Lambda+Cloud WatchでEC2インスタンスを自動停止・自動起動する

f:id:yokoyantech:20171013193730p:plain

やりたいこと

  • 毎日定時にEC2を自動停止・自動起動したい
  • 停止
    • 毎週月~金の18時(JST)に停止
  • 起動
    • 毎週月~金の9時(JST)に起動
  • できるだけお金をかけたくない
    • 自動起動・停止のためだけに、EC2にJenkinsを入れて、起動しっぱなしにすることはやめる
    • サーバーレスでやってみよう!

参考情報

以下の記事を参考にさせていただきました。
LambdaとCloudWatch EventsでEC2の自動起動&自動停止をやってみた(Python版)

Lambda関数の作成

ステップ1 設計図の選択

関数の作成をクリックする。

image

一から作成をクリック。

image

ステップ2 トリガーの設定

次へをクリック。

image

ステップ3 関数の設定

  • 名前
    • 任意(例:StopEC2Instances)
  • 説明
    • 任意(例:stops EC2 instances every day at night)
  • ランタイム
    • Python 2.7
import boto3

region = 'ap-northeast-1'
# Enter your instances here: ex. ['X-XXXXXXXX', 'X-XXXXXXXX']
instances = ['X-XXXXXXXX']
def lambda_handler(event, context):
    ec2 = boto3.client('ec2', region_name=region)
    ec2.stop_instances(InstanceIds=instances)
    print 'stopped your instances: ' + str(instances)    

IAM Roleの作成

カスタムロールの選択を選ぶ。 image

IAM画面が開くので以下を設定。 - IAMロール:「新しいIAMロールの作成」 - ロール名:任意(例:lambda_start_stop_ec2)

次にポリシードキュメントを表示をクリック。 image

以下のポリシーを追加する。

{
  "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": "*"
    }
  ]
}

追加し終わったら、許可をクリック。 image

Lambda設定の続き

先ほど作成したIAMロールが選択されていることを確認して、次へをクリック。 image

ステップ4 確認

問題なければ、関数の作成をクリックする。 image

エラーがなければ、関数が作成される。 image

EC2インスタンス起動関数の作成

上記と同じ手順で、EC2起動用の関数を作成する。

  • 名前
    • 任意(例:StartEC2Instances)
  • 説明
    • 任意(例:start EC2 instances every day at morning)
  • ランタイム
    • Python 2.7
import boto3

region = 'ap-northeast-1'
# Enter your instances here: ex. ['X-XXXXXXXX', 'X-XXXXXXXX']
instances = ['X-XXXXXXXX']
def lambda_handler(event, context):
    ec2 = boto3.client('ec2', region_name=region)
    ec2.start_instances(InstanceIds=instances)
    print 'started your instances: ' + str(instances)

ロールは先ほど作成した、IAMロールを選択する。 image

CloudWatch Eventsの設定

EC2停止ルールの作成

CloudWatch Eventsの画面を開き、イベントをクリックし、ルールの作成をクリックする。 image

以下の設定を行う。

  • パターン:スケジュール
  • 設定:Cron式
    • 分 時間 日 月 曜日 年
    • 0 18 ? * MON-FRI * 毎週月曜から金曜日までの午前9時(UTC)に実行 →UTC時間の時差が9時間あるため、午後18時(JST)となる。

スケジュールを入力して、以後10回のトリガー日が出てこない場合は、Cron式が誤っている可能性があるので注意すること。 image

右側のターゲットの追加をクリックして、Lambda関数を選択する。 EC2停止用の関数を選択し、設定の詳細をクリックする。 image

ステップ2 ルールの詳細を設定する

任意の値を入力する

  • 名前:任意(例:StopEC2Instances)
  • 説明:任意(例:stops EC2 instances every day at night)

image

エラーが無ければ、ルールが作成される。 image

EC2起動ルールの作成

以下の設定を行う。

  • パターン:スケジュール
  • 設定:Cron式
    • 分 時間 日 月 曜日 年
    • 0 0 ? * MON-FRI * 毎週月曜から金曜日までの午前0時(UTC)に実行 →UTC時間の時差が9時間あるため、午前9時(JST)となる。
  • Lambda関数:EC2起動用関数

image

任意の値を入力する

  • 名前:任意(例:StartEC2Instances)
  • 説明:任意(例:start EC2 instances every day at morning)

エラーが無ければ、ルールが作成される。 image

動作確認

スケジューリングされたLambda関数の実行結果は、CloudWatchイベントのログから確認できる。 image

おわりに

サーバレスで維持費をできる限り0円に近づけることができました。 このやり方だと、Lambda関数内にインスタンスIDをべた書きしないといけないので、今後改良していきます。