はじめに
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イベントルールを設定
- ルールを作成する
- イベントソース
- スケジュール
- Cron 式:
0 0 ? * MON-FRI *
(月曜~金曜日の09:00に起動)
UTCで指定する
- Cron 式:
- スケジュール
- ターゲット
- Lambda関数
EC2instancesStartStop
- 入力の設定
- 定数 (JSON テキスト):
{"Action": "Start", "RegionName": "ap-northeast-1", "InstanceIds": ["i-00000000000000000"]}
Action(Start/Stop)、EC2のリージョンとインスタンスIDを指定する
- 定数 (JSON テキスト):
- Lambda関数
- イベントソース
同様に停止させるルールも作成する
祝日および特定日も停止させる
事前に祝日および特定日リストを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
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