AWS Lambda

【lambda】特定タグが付いているEC2インスタンス以外を、終了。

ごあいさつ

こんばんは。
最近、暑すぎてつらいもに倉です。

今回は、特定のタグ(Using:yes)が付いているEC2インスタンス以外を
終了(削除)させるlambdaを作成したのでご紹介します。

命名規則とかそういうものはガン無視していますが、許してください。

使ったもの

lambda(Python 3.9)
※メモリやタイムアウト設定を多めにとっています。様子を見てちょうどいい設定にしてください。

中身

コード

import boto3
#↓これがないとエラー回避できない
from botocore.exceptions import ClientError

def lambda_handler(event, context): 
    ec2 = boto3.client('ec2')

    all_instances = ec2.describe_instances()
#↓特定タグのついたインスタンスを抽出
    tag = ec2.describe_instances(
        Filters=[{ 'Name': 'tag:Using', 'Values':  ['Yes', 'yes'] }]
    )

#↓すべてのインスタンス群と特定タグ付きインスタンス群を用意
    all_instances_set = set(ec2['InstanceId'] for resId in all_instances['Reservations'] for ec2 in resId['Instances'])
    tag_set = set(ec2['InstanceId'] for resId in tag['Reservations'] for ec2 in resId['Instances'])

#↓すべてのインスタンス群から特定タグ付きインスタンス群を取り除いて、特定タグの付いていないインスタンス群を抽出
    delete_instances = all_instances_set - tag_set
    delete_instances_list = list(delete_instances)

#こだわりポイント(後述)
    if len(delete_instances_list) != 0:
        for delete_instance in delete_instances_list:
            try:
                ec2.modify_instance_attribute(
                    DisableApiTermination={
                    'Value': False
                    },
                    InstanceId=delete_instance
                )

            except ClientError as e:
                pass

#↓特定タグの付いていないインスタンスを終了(削除)
            terminateInstances = ec2.terminate_instances(
            InstanceIds=delete_instances_list
            )

流れとしては、
①今あるEC2インスタンスを全部取得
②特定タグの付いていないインスタンスを抽出
③終了保護を無効化←こだわり
④インスタンスを終了(削除)
というかんじです。

こだわりポイントの解説

びっくりするくらいトーシロですが、ちょっとだけこだわりを解説してみます。

タグをつけていないほうが悪いので、終了保護を有効化していても容赦なく削除するようにしました。

ec2.modify_instance_attribute(
                    DisableApiTermination={
                    'Value': False
                    },
                    InstanceId=delete_instance
                )

このように、削除対象のインスタンスの終了保護を無効化する工程を挟んでいます。

しかしこの工程、すでに「終了済み(Terminated)」となっているインスタンスが存在すると
エラーになってしまいます。errorTypeはClientErrorです。

そこで、そのエラーを回避するための材料がこちら↓

from botocore.exceptions import ClientError

            except ClientError as e:
                pass

これで、ClientErrorが出ても無視して動いてくれます! 嬉しいね。

あとがき

わからないなりに、いろんな人の力を借りながら作ることができました。
RDSを消すlambdaも作成中……(ドン詰まり中)。

返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA