背景
コスト削減のため、深夜帯で起動する必要性がないEC2は自動で停止をEventBridgeで行う。
本来EventBridgeだけでEC2の停止のスケジュールは可能ですが、タグでフィルターができないためLambda構成としております。
ゴール
20時で『PowerManagement』タグが付いているEC2を自動で停止させる
EventBridge
イベントバス作成
イベントバスとは、イベントの発生源とターゲットの仲介役となる設定。
イベントバス内でJsonを評価するなどしてターゲットの送信先を選ぶなどが可能
だが今回はcron式のため、ほとんど使わないが作成だけはしておく。
●イベントバスに関するドキュメント
https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-event-bus.html
暗号化やリソースベースポリシーは設定しない
リソース間で連携させる場合には、EventBridgeに対して別のAWSリソースへのアクセスを許可する必要性がある
スケジュールグループ作成
スケジュールのタスク実行を行うためにはスケジュールグループを作成する
「test_schedulegroup」という名前のスケジュールグループを作成
次にスケジュールグループにスケジュールを設定する
「名前」:任意
「スケジュールグループ」は先ほどのスケジュールグループ選択
「定期的なスケジュール」を選択
「タイムゾーン」に「Asia/Tokyo」⇒「cron式」を入力
タイムゾーンを日本にしているため、UTC時間を日本時間に変換する必要などはありません。
cron(0 20 * * ? *)
Lambda関数はまだ作成していないので「新しい関数を作成」を選択⇒Python3.3のLambda関数
一旦関数の中身については後から作成するのでコードは適当で保存してください
ペイロードは空白でOK
「スケジュールの有効化」をオン(画像はオフになってますがオンで良い)
「スケジュール完了後のアクション」をNONE
他はデフォルトでおk
上記設定が完了し、作成を選択します(少し時間がかかる)
Lambda関数作成
続いて、EC2を起動するLambda関数を作ります。
EC2の情報取得する関数
boto3はPythonのAWSのSDK
下記がアカウント内のEC2を全て取得するコード
import boto3
ec2 = boto3.client('ec2')
def lambda_handler(event, context):
response = ec2.describe_instances()
下記がEC2を停止するコード
instance_ids = ["<インスタンスID>"]
response = ec2.stop_instances(InstanceIds=instance_ids)
ec2.stop_instancesの引数は配列にしないとエラー出るみたい。。。
上二つを組み合わせて今回はVPC情報とタグ情報とEC2の状態でEC2をフィルターし、インスタンスを停止するLambda関数を作成します。
import boto3
ec2 = boto3.client('ec2')
def lambda_handler(event, context):
vpc_id = "<VPCのID>"
Filters = [
{'Name': 'vpc-id', 'Values': [vpc_id]},
{'Name': 'tag:PowerManagement', 'Values': ['ON']},
{'Name': 'instance-state-name', 'Values': ['running']}
]
response = ec2.describe_instances(Filters=Filters)
# インスタンス停止処理
instance_ids = []
for reservation in response['Reservations']:
for instance in reservation['Instances']:
instance_ids.append(instance['InstanceId'])
result = ec2.stop_instances(InstanceIds=instance_ids)
print(f"停止処理結果: {result}")
作成したLambda関数に上記コードを張り付けて保存します。
Lambda関数の保存には、左下の「Deploy」をクリックします。
コードにエラーがなければ正常に更新されます。
Lambdaをテスト
対象のVPC内にPowerManagementというキーでONというvalueを持つタグを持つEC2を立ち上げます。
「テスト」タブを開いて「テスト」をクリックします。(入力は必要ない関数のため、Jsonは書き換え不要)
また、「テスト」が完了するとpythonのprint文の出力などがCloudWatchLogsに出力されています。
ちなみに、resultの中身はこんな感じです。(APIの結果が返ってきてます)