見出し画像

特定のタグが付いた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つ同時にすることが確認できました。

この記事が気に入ったらサポートをしてみませんか?