特定のタグが付いたEC2を停止、起動するLambda関数 1 - python 3(boto3) -
必要に迫られて作りました。晒しておきます。
環境変数projectに設定した値と、同じタグがついているEC2インスタンスを停止、起動させるLambda関数を作ります。
今回は、Lambdaに登録する前にローカルから実行確認するところまでを紹介します。
コード
コピペして「stop_start-ec2.py」と名前をつけて保存します。
今回は、せっかくなので、boto3.resourceを使いました。
ネットに転がっていた情報では、boto3.clientを使うサンプルが多かったです。が、EC2インスタンスの起動停止は、boto3.resourceでサポートされているので、clientよりresourceを使ったほうが簡単にかけます。
import boto3
import os
ec2_resource = boto3.resource('ec2')
# tag:projectを環境変数から読み取る。対象のタグが付いているEC2インスタンスをすべて落とすスクリプト。
def stop_ec2(event, context):
action='stop'
print('%s EC2 Start' %action.capitalize() )
# project_idの取得
project_id = os.environ.get('project')
if not project_id:
raise Exception('$project is empty')
# project_idがついたEC2インスタンスを取得
instances = ec2_resource.instances.filter(
Filters=[{'Name': 'tag:project', 'Values': [project_id]}]
)
if not list(instances):
raise Exception('Target Instance is None')
# 対象のEC2インスタンス(すべて)を停止
response = instances.stop()
print('%s EC2 Complate' %action.capitalize() )
print(response)
# tag:projectを環境変数から読み取る。対象のタグが付いているEC2インスタンスをすべて起動するスクリプト。
def start_ec2(event, context):
action='start'
print('%s EC2 Start' %action.capitalize() )
# project_idの取得
project_id = os.environ.get('project')
if not project_id:
raise Exception('$project is empty')
# project_idがついたEC2インスタンスを取得
instances = ec2_resource.instances.filter(
Filters=[{'Name': 'tag:project', 'Values': [project_id]}]
)
if not list(instances):
raise Exception('Target Instance is None')
# 対象のEC2インスタンス(すべて)を起動
response = instances.start()
print('%s EC2 Complate' %action.capitalize() )
print(response)
# ローカルPCから実行するとき用
if __name__ == "__main__":
event = ""
context = ""
import time
stop_ec2(event, context)
time.sleep(120)
start_ec2(event, context)
テスト用EC2の準備
2つのEC2インスタンスを作成します。
次に、それぞれ別のprojectタグをつけます。
ローカルPCから実行
Windowsのgit bashから実行します。
コードの実行前に、環境変数projectを設定します。
ちなみに、ローカルPCから実行するときは、2つの関数をまとめてテストするため、停止、120秒待ち、起動という処理を続けて行っています。Lambda関数として登録する際は、別々の関数として登録してCloudwatch Ruleなどから利用します。
$ export project=a
$ python stop_start-ec2.py
Stop EC2 Start
Stop EC2 Complate
[{'StoppingInstances': [{'CurrentState': {'Code': 64, 'Name': 'stopping'}, 'InstanceId': 'i-031d66b861d065137', 'PreviousState': {'Code': 16, 'Name': 'running'}}], 'ResponseMetadata': {'RequestId': '34a69092-a5f4-4fd7-bf54-53da93ff141f', 'HTTPStatusCode': 200, 'HTTPHeaders': {'content-type': 'text/xml;charset=UTF-8', 'content-length': '579', 'date': 'Sat, 23 Mar 2019 02:05:32 GMT', 'server': 'AmazonEC2'}, 'RetryAttempts': 0}}]
Start EC2 Start
Start EC2 Complate
[{'StartingInstances': [{'CurrentState': {'Code': 0, 'Name': 'pending'}, 'InstanceId': 'i-031d66b861d065137', 'PreviousState': {'Code': 80, 'Name': 'stopped'}}], 'ResponseMetadata': {'RequestId': '89c79f2e-0fcb-490e-ad5e-64383296457f', 'HTTPStatusCode': 200, 'HTTPHeaders': {'content-type': 'text/xml;charset=UTF-8', 'content-length': '579', 'date': 'Sat, 23 Mar 2019 02:07:33 GMT', 'server': 'AmazonEC2'}, 'RetryAttempts': 0}}]
確認
タグ project aがついたEC2インスタンスタンスが停止していることが確認できます。
120秒後、特定のタグがついたインスタンスだけが、起動することが確認できました。
停止起動対象インスタンスが複数の場合
タグの変更
2つ目のインスタンのタグを1つ目と同じ(project a)に変更します。
実行
$ python stop_start-ec2.py
Stop EC2 Start
Stop EC2 Complate
[{'StoppingInstances': [{'CurrentState': {'Code': 64, 'Name': 'stopping'}, 'InstanceId': 'i-031d66b861d065137', 'PreviousState': {'Code': 16, 'Name': 'running'}}, {'CurrentState': {'Code': 64, 'Name': 'stopping'}, 'InstanceId': 'i-0ffba399c851a48bb', 'PreviousState': {'Code': 16, 'Name': 'running'}}], 'ResponseMetadata': {'RequestId': '859db0fd-9b45-4a9a-b44f-5a27fd32418d', 'HTTPStatusCode': 200, 'HTTPHeaders': {'content-type': 'text/xml;charset=UTF-8', 'content-length': '918', 'date': 'Sat, 23 Mar 2019 02:10:19 GMT', 'server': 'AmazonEC2'}, 'RetryAttempts': 0}}]
Start EC2 Start
Start EC2 Complate
[{'StartingInstances': [{'CurrentState': {'Code': 0, 'Name': 'pending'}, 'InstanceId': 'i-031d66b861d065137', 'PreviousState': {'Code': 80, 'Name': 'stopped'}}, {'CurrentState': {'Code': 0, 'Name': 'pending'}, 'InstanceId': 'i-0ffba399c851a48bb', 'PreviousState': {'Code': 80, 'Name': 'stopped'}}], 'ResponseMetadata': {'RequestId': '47611afe-4ec4-47ff-8509-b9aea07c3956', 'HTTPStatusCode': 200, 'HTTPHeaders': {'content-type': 'text/xml;charset=UTF-8', 'content-length': '916', 'date': 'Sat, 23 Mar 2019 02:12:20 GMT', 'server': 'AmazonEC2'}, 'RetryAttempts': 0}}]
ログの出力からも対象のインスタンスが、2つになっていることが読み取れます。
確認
2つ同時に停止することが確認できます。
起動も120秒後、2つ同時にすることが確認できました。