EC2の自動起動・停止を自動化させたい
社内用のサーバーなどで常時起動しておく必要のないサーバーを夜になったら自動で停止、朝になったら自動で開始をさせたいという要望がありました。
単純に開始処理と停止処理をLambdaで書いて起動や停止をさせればいいのですが、時間の変更や、一時的に停止をやめたり、開始をやめたりなどカスタム性を考えるとEC2のタグで管理できると楽だなという結論になりました。
上記画像のようにEC2のタグに開始時刻と停止時刻を書いてしまうという運用です。不要なればタグを外すだけです。
以下のスクリプトでできました。
hour_rounderという関数で時刻を丸めているのですが、これはいらないかもですが念の為にやっています。
あとはこのLambdaをEvent Bridgeで毎時呼び出すだけです。
LambdaのロールにはEC2の起動・停止の権限をお忘れなく!
import json
import boto3
from datetime import datetime, timedelta, timezone
ec2 = boto3.client('ec2', region_name='ap-northeast-1')
def lambda_handler(event, context):
JST = timezone(timedelta(hours=+9), 'JST')
now = datetime.now(JST)
# 時刻処理 現在に最も近い0分の時間を取得
# 例 12時10分 → 12時 4時40分 → 5時
def hour_rounder(t):
return (t.replace(second=0, microsecond=0, minute=0, hour=t.hour) + timedelta(hours=t.minute//30))
hour_rounded_time = hour_rounder(now)
hour = str(hour_rounded_time.hour)
# 停止処理
custom_filter = [{
'Name':'tag:auto_stop_at',
'Values': [hour]}]
response = ec2.describe_instances(Filters=custom_filter)
stop_instance_ids = []
for instance_dic in response['Reservations']:
stop_instance_ids.append(instance_dic['Instances'][0]['InstanceId'])
if stop_instance_ids:
ec2.stop_instances(InstanceIds=stop_instance_ids)
# ここから開始処理
custom_filter = [{
'Name':'tag:auto_start_at',
'Values': [hour]}]
response = ec2.describe_instances(Filters=custom_filter)
start_instance_ids = []
for instance_dic in response['Reservations']:
start_instance_ids.append(instance_dic['Instances'][0]['InstanceId'])
if start_instance_ids:
ec2.start_instances(InstanceIds=start_instance_ids)
return {
'statusCode': 200,
'start_instance_ids': start_instance_ids,
'stop_instance_ids': stop_instance_ids
}