[AWS][Python]Lambdaでタグを判別してEC2インスタンスを削除するスクリプトを作ってみた

みなさんこんにちは!
12月に入社しました、 インフラストラクチャー部のあだちん(安達)です。
まだ入社したばかりなのに、もうブログ書くの!?
てな感じですが笑

さてさて、 medibaでは検証としてAWSを思う存分使える制度があります。
(hoge万円まで)→素晴らしい

しかし、開発メンバーらが、そのままインスタンス起動しっぱなしで、
コストが上がったり。。
セキュリティーグループなどぐちゃぐちゃ。。
インフラメンバーが毎回コンソール入って一つ一つ確認するのは
とても荷が重い。。。。

今回はLambdaを使用して定期的に
EC2インスタンスを自動削除するスクリプトを作ってみました。

image

今回やりたいこと

・EC2、EBS、ELB、などの動いているサービスを3ヶ月に一回は自動削除する
・タグで判別し、削除したくないものはそのままにする
・せっかくなのでサーバ建てない「Lambda」でスクリプトを動かしたい

準備するもの

・Lambda
・Python2.7
・boto3

Mac初期設定

1.ローカル(Mac)にaws cliをbrewでインストール
2.IAMで自分のユーザ作成とaws cliを動かせるようにする

基本AWSのインスタンス情報はJSONで返ってきます。
実際にMac から以下のコマンドを打つとダーッと情報が出てくると思います。

$ aws ec2 describe-instances

この情報とともにPython(boto3)と組み合わせてプログラムを作るイメージです。

Lambda初期設定

3.IAMにLambda用ロールを新規で作成する
ポリシー名は以下を追加します。(これらを追加しないと実行できません。)

・AmazonEC2FullAccess
・CloudWatchActionsEC2Access
・AWSLambdaVPCAccessExecutionRole

4.Lambdaのコンソールを開き、新規で作成する

image

5.各種設定
imageimage

6.EC2インスタンスをタグ判別してterminate(削除)するスクリプトの紹介


#Keyがnodelete、Valueがtrue以外は削除
# coding: utf-8
import boto3
#
def lambda_handler(event, context): 
#if __name__ == '__main__': #EC2上で叩く場合
    client = boto3.client('ec2', "ap-northeast-1")
    resp = client.describe_instances()
    all_list = []
    del_list = []
    for reservation in resp['Reservations']:
      for instance in reservation['Instances']:
        all_list.append(instance['InstanceId'])
        #print(all_list)
        if 'Tags' in instance:

          for tag in instance['Tags']:
            if tag['Key'] == 'nodelete' and tag['Value'] == 'true':
              del_list.append(instance['InstanceId'])
              #print(del_list)

    diffset = set(all_list) - set(del_list)
    #print(diffset)
    targetlist = list(diffset)
    print(targetlist)
    #問題なければ以下のコメントアウトを外して削除してみる
#   ec2.terminate_instances( 
#        InstanceIds=targetlist              
#   )

今回Keyを「nodelete」Valueが「true」以外
のものはインスタンスterminate(削除)
します。
つまり、上記のタグにしとけば消えることはありません。

7.実際にテストをしてみる

image

まずは対象のインスタンスIDが出力されるか確認しましょう。
問題なければterminateする部分(下から3行目)をコメントアウト外して
インスタンスがterminateされたらOKです。

8.先程作ったスクリプトを定期的に実行する

Cloud Watchからイベントでルールの新規作成をします。
スケジュールを選択肢し、
ターゲットの追加で先程のLambdaを以下のように追加します。
追加するとLambdaのマネジメントコンソールから
Triggerに反映されているはずです。

まとめ

Python初心者ですが、わざわざインスタンス建てなくても
Lambdaで問題なく削除することができました。(コスト削減)
まだ開発途中ですが、全サービス削除できるスクリプトが仕上がったら、
またブログでお会いしましょう!
(もっと改めて運用考えねば…)

参考:https://boto3.readthedocs.io/en/latest/