LoginSignup
12
10

More than 3 years have passed since last update.

【AWS】EC2を平日日勤帯のみ稼働させる

Posted at

はじめに

EC2はお手軽な仮想環境として便利なサービスですが、
稼働時間に応じた従量課金のため使わない時間帯は停止させたい。
LambdaとCloudWatchイベントを使って平日夜間と土日は停止させる。
さらに祝日や特定日など任意日も停止させる。

LambdaとCloudWatchイベントでEC2を開始/停止

LambdaとCloudWatchイベントで指定したEC2インスタンを自動で開始/停止させる

Lambda関数を用意

  • EC2instancesStartStop
lambda_function.py
import boto3

def lambda_handler(event, context):
    region_name = event['RegionName']
    instance_ids = event['InstanceIds']
    ec2 = boto3.client('ec2', region_name=region_name)
    if event['Action'] == 'Start':
        ec2.start_instances(InstanceIds=instance_ids)
    elif event['Action'] == 'Stop':
        ec2.stop_instances(InstanceIds=instance_ids)

CloudWatchイベントルールを設定

event.png

  • ルールを作成する
    • イベントソース
      • スケジュール
        • Cron 式: 0 0 ? * MON-FRI * (月曜~金曜日の09:00に起動)
          UTCで指定する
    • ターゲット
      • Lambda関数 EC2instancesStartStop
      • 入力の設定
        • 定数 (JSON テキスト): {"Action": "Start", "RegionName": "ap-northeast-1", "InstanceIds": ["i-00000000000000000"]}
          Action(Start/Stop)、EC2のリージョンとインスタンスIDを指定する

同様に停止させるルールも作成する

祝日および特定日も停止させる

事前に祝日および特定日リストをS3にファイルとしてアップロードしリストに含まれる日付の場合はスキップさせます。

  • EC2instancesStartStop
lambda_function.py
import boto3
import os
import datetime

class Holiday():
    @classmethod
    def isHoliday(self):
        os.environ['TZ'] = 'Asia/Tokyo'
        day = datetime.date.today()
        today = day.strftime("%Y%m%d")
        print(today)

        try:
            if len(os.environ['HOLIDAY_DATA_BUCKET']) > 0:
                s3 = boto3.resource('s3')
                bucket = s3.Bucket(os.environ['HOLIDAY_DATA_BUCKET'])
                obj = bucket.Object('holiday.dat')
                with open('/tmp/holiday.dat', 'wb') as data:
                        obj.download_fileobj(data)
                f = open('/tmp/holiday.dat')
                holidays = f.readlines()
                f.close()
                os.remove('/tmp/holiday.dat')

                check = today + "\n" in holidays
                return check
            else:
                return False
        except Exception as e:
            print 'failed to isHoliday: {}'.format(e)
            return False

:information_source: python2.7のLambdaではタイムゾーンの設定に os.environ['TZ'] = 'Asia/Tokyo' が反映されますが、
python3.6ではLambdaの環境変数に TZ : Asia/Tokyo を設定する必要があります

lambda_function.py
#  (該当箇所に追記)
import check_holiday

    if check_holiday.Holiday.isHoliday() == True:
        print "== SKIP == today is holiday =="
        return None

環境変数に特定日リストファイルを置くバケット名を指定します
HOLIDAY_DATA_BUCKET: <BUCKET_NAME>

  • 特定日リスト
holiday.dat
20190429
20190430
20190501
20190502
20190503
20190504
20190505
20190506

祝日リストは下記コマンドでGoogleカレンダーから取得可能です。

$ curl -L https://www.google.com/calendar/ical/ja.japanese%23holiday%40group.v.calendar.google.com/public/basic.ics | grep DTSTART\;VALUE=DATE\:|sed -e 's/DTSTART\;VALUE=DATE\://g'|sort > holiday.dat
12
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
10