使っていないインスタンス、EBSの削除、EIPの開放をAWS Lambdaで実行するためにPythonでスクリプトを書いてみた
import boto3 def lambda_handler(event, context): regions = ["ap-northeast-1","us-east-1"] for region in regions: ec2_client = boto3.client("ec2",region_name=region, aws_access_key_id="*****",aws_secret_access_key="*****") #インスタンスIDを受け取って削除保護されているかどうかを調べる関数 def check_lock(id): return ec2_client.describe_instance_attribute(Attribute='disableApiTermination',InstanceId=id)["DisableApiTermination"]["Value"] #既にterminatedになっているインスタンスに下の処理を実行しようとするとエラーが出たので、ここでterminatedを除いている instances = ec2_client.describe_instances(Filters=[{"Name": "instance-state-name", "Values": ["pending","running","shutting-down","stopping","stopped"]}])["Reservations"] for reservation in instances: for instance in reservation["Instances"]: instance_id = instance["InstanceId"] #"インスタンスを削除したらEBSも削除する"設定をした後に、インスタンスを削除している if not check_lock(instance_id): ebs_name = instance["BlockDeviceMappings"][0]["DeviceName"] ec2_client.modify_instance_attribute(BlockDeviceMappings=[{"DeviceName": ebs_name, 'Ebs': {'DeleteOnTermination': True}}],InstanceId=instance_id) ec2_client.terminate_instances(InstanceIds=[instance_id]) for address in ec2_client.describe_addresses()["Addresses"]: #削除保護されているインスタンスに対応付けられたEIPは開放しないようにしてある if "InstanceId" in address and address["InstanceId"]: if check_lock(address["InstanceId"]): continue allocation_id = address["AllocationId"] ec2_client.release_address(AllocationId=allocation_id)
全15リージョン全てについて処理を実行できたらいいなと思ったがやけに時間がかかるので2リージョンのみでもたまに実行時間が長くなりすぎてtimeoutになってしまう。(デフォルトのタイムアウト時間は3000msだった。)
今回はタイムアウト時間を伸ばして2リージョンに対して実行することにした。リージョンの数に応じてタイムアウトの時間を伸ばすことをおすすめする。
どの部分で時間がかかっているのかと思い時間を測ったところ、クライアントの取得で最も時間がかかっていた。
例えば、全体の実行時間が616msでクライアントのインストールにかかる時間が597msなどとなった。
このスクリプトは実行時間のばらつきも大きいのだが、これに関して本当にわからん…