AWS Lambda

Lambdaで3日間使用していないEBSを削除する

はじめに

こんにちは、omkです。
引き続き社内のAWS検証環境のコスト削減に取り組んでいるところです。
前回は使用されていないElasticIPを解放するLambdaを用意しました。↓
https://blog.denet.co.jp/release-eip/

EIPと同様に、EC2インスタンスも終業後に特定のタグをつけていない場合に削除する方針で進めております。ただ、タグの付け忘れで大事な検証サーバを消してしまうと業務に影響が出てしまうのでEBSだけは何日か置いておいて一度もアタッチされなかったら消してしまおうと思います。

実装

CloudWatch Eventsで時間を指定してLambdaのトリガーにします。
今回もLambdaはruby2.7でAWS SDKを用いて書きます。
毎日カウントダウンを行い(CloudWatchEventsで毎日起動する)、3日間「in-use」にならなかったボリュームを削除します。
カウントダウンはタグ「AutoDelete」をつけてその値(数字)で残日数を管理します。

require 'json'
require 'aws-sdk'

# アタッチされていないEBSボリュームの削除
def lambda_handler(event:, context:)
    # ボリューム一覧の取得
    ec2_client = Aws::EC2::Client.new(region: "ap-northeast-1")
    volumes = ec2_client.describe_volumes

    # ボリュームの状態確認
    for i in 0..(volumes[0].length - 1)
        v_id = volumes[0][i].volume_id
        v_state = volumes[0][i].state
        if(v_state == "in-use") then
            # EBSが使用されているとき削除タグの削除
            vv = Aws::EC2::Volume.new(v_id)
            v_tags = vv.tags
            for j in 0..(v_tags.length - 1)
                if(v_tags[j].key == "AutoDelete")
                    # タグを上書きしてから消す(力技)
                    vv.create_tags({
                        tags: [ 
                            {
                                key: "AutoDelete",
                                value: "true",
                            },
                        ],
                    })
                    vv.delete_tags({
                        tags:
                        [
                            {
                                key: "AutoDelete",
                                value: "true"
                            }
                        ]
                    })
                    break
                end
            end

        elsif(v_state == "available") then
            # 利用されていないリソースなので3日後に消す
            vv = Aws::EC2::Volume.new(v_id)
            isSetAutoDelete = false
            v_tags = vv.tags
            # タグに削除タグがあるとき残日数を確認
            for j in 0..(v_tags.length - 1)
                if(v_tags[j].key == "AutoDelete")
                    # 値が数字か判断して数字なら下げる、残日数が0日になればボリュームを消す
                    days = v_tags[j].value.to_i
                    if(days >0) then
                        # 0より大きい(数字以外の文字だけの時は0になる)
                        isSetAutoDelete = true
                        days -= 1
                        vv.create_tags({
                            tags: [ 
                                {
                                    key: "AutoDelete",
                                    value: days.to_s,
                                },
                            ],
                        })
                    elsif(v_tags[j].value <= "0")
                    # 0以下の時(消す日)
                        isSetAutoDelete = true
                        vv.delete()
                        break
                    end
                end
            end
            # AutoDeleteタグが付いていない場合ここでつける、3日後消す
            if(!isSetAutoDelete)
                vv.create_tags({
                    tags: [ 
                        {
                            key: "AutoDelete",
                            value: "3",
                        },
                    ],
                })
            end
        end
    end
end

流れとしてはまずボリュームの一覧を取得します。
次にそれぞれの「state」を確認し、「in-use」なら「AutoDelete」タグを消します。
「available」ならボリューム削除の対象です。
「AutoDelete」タグを確認して、値が0より大きければ1減らします。0になればボリュームを消します。「AutoDelete」タグが付いていない場合はご新規さんなのでタグをつけて値を3にします。
値はstringで入るので一度intに変換して、計算してからstringに戻してタグに入れます。
これで3日後に消えるEBSの設定は終わりです。

まとめ

作成日時などの時間は用意されていても自分の欲しい条件の時間がクラスに含まれないときはこういう風にタグで管理するのもいいですね。

EC2インスタンスを消してもEBSが残るのは忘れがちで検証環境にも使用していないEBSが溜まっていたので、これを作成しました。
皆で適切なリソース管理を模索しましょう。

返信を残す

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

CAPTCHA