メインコンテンツへスキップ

LambdaでSnapshot定期削除,リージョンコピー

    ソースコード(定期削除)

    import boto3
    import datetime
    def lambda_handler(event, context):
        client=boto3.client('ec2')
        DELETE_DAY=7  #削除対象の経過日数
     ### 指定のタグをフィルターし、削除対象のスナップショット情報を取得する
        snapshot=client.describe_snapshots(
            Filters=[
                {
                    'Name':'tag:system',
                    'Values':[
                       'test'
                    ]
                },
            ]
        )['Snapshots']
        length=len(snapshot)
     ### スナップショット作成日時と今日の日付の差が7日より大きいスナップショットを削除する
        for i in range(length):
            snapshot_starttime=snapshot[i]['StartTime']
            if (datetime.date.today() - snapshot_starttime.date()).days > DELETE_DAY :
                client.delete_snapshot(SnapshotId=snapshot[i]['SnapshotId'])

    特に注記はないです、はい。
    json形式のレコードから要素取り出すの面倒くさくて嫌だよね。

    ソースコード(リージョンコピー)

    import boto3
    import time
    import datetime
    def lambda_handler(event, context):
        client=boto3.client('ec2')
        DESTINATION_REGION='ap-northeast-3'
        SOURCE_REGION='ap-northeast-1'
        snapshot_id=[]
        SNAPSHOT_COMPLETE_COUNT=0
     ### 指定のタグをフィルターし、バックアップ対象のスナップショット情報を取得
        snapshot=client.describe_snapshots(
            Filters=[
                {
                    'Name':'tag:system',
                    'Values':[
                        'test'
                    ]
                },
            ]
        )['Snapshots']
    ### 取得したスナップショットの作成日が今日のもののIDをsnapshot_idに格納
        length=len(snapshot)
        for i in range(length):
            snapshot_starttime=snapshot[i]['StartTime']
            if snapshot_starttime.date()==datetime.date.today():
                    snapshot_id.append(snapshot[i]['SnapshotId'])
    
    ### snapshotのステータスの数をカウントする
        def check_snapshot(COUNT):
            for i in range (length):
                 if snapshot[i]['State']=='completed':
                    COUNT+=1
            return COUNT
        
        result=check_snapshot(SNAPSHOT_COMPLETE_COUNT)
    ### snapshotのステータスcompleteの数とsnapshotの数が一致しない場合15秒待機し、ステータスチェックを実行を繰り返す
        while result!=length:
             time.sleep(15)
             SNAPSHOT_COMPLETE_COUNT=0
             result=check_snapshot(SNAPSHOT_COMPLETE)
    ### snapshot_idに格納したスナップショットを大阪リージョンにコピーする
        client_osaka=boto3.client('ec2',region_name=DESTINATION_REGION)
        length=len(snapshot_id)
        for i in range(length):
            client_osaka.copy_snapshot(
                SourceRegion=SOURCE_REGION,
                SourceSnapshotId=snapshot_id[i],
                TagSpecifications=[
                    {
                        'ResourceType':'snapshot',
                        'Tags':[
                            {
                                'Key':'system',
                                'Value':'test'
                            }
                        ]
                    }
                ]
            )
    

    リージョンコピーに関しては、少し注記をば。

    注記

    元々の想定では前回のスナップショットの作成後にこいつを呼び出して、削除やらリージョンコピーの計画だったので、スナップショット作成中にリージョンコピー動かすわけにいかんので、全部completedになるまで待ちの動きにしている。想定としてはpending→completed待ちなのだが、実際errorになったりするので、その辺はタイムアウトだろーなーと思っている。
    日次実行でその辺を許容するか、いい感じにいじるかは任せるので上手く運用してつかあさい。

    そして、copy_snapshot()でリージョン間コピーする場合は気を付けたいのが、clientセッションはコピー先になる。
    公式ドキュメント内で書き方がちょっとうーーんというところもあり、
    確かにパラメータとしてDestinationRegionは記載はあるもののRequestSyntaxに記載がない。これをclientセッション東京で、DestinationRegionを大阪などに指定しても、コピー先は東京になるので、describe_snapshot()のclientは東京、copy_snapshot()は大阪にセッション指定しなおすことが必要になる。

    また、リージョン間コピーの一度に実行できる数は20までなので、この辺りも気を付けたい。実際の運用ではもう少し考慮した形になるのではと思う。

    以上です。

     
     

    お尻

     
     
    こんにちは、ポンコツエンジニアやってます。フリーランスはじめました。 技術記事書いたり、NHKラジオや洋本読んで、読書感想文書いたり、情報系勉強したくなくて英語、フランス語勉強したり…仕事辞めて語学学校行ったり…合気道教室行ったり、 飽き性で続かんなりに細々色んなこと書いてます。

    あなたへのおすすめ