LambdaでS3のデータを1日1回クリアする

バッチのテンポラリで使うS3バケットのデータを1日1回綺麗にクリアしたくてやり方を調べました。

最初はS3のライフサイクルポリシーでやろうと思ったのですが、削除タイミングが思い通りに設定できない、綺麗に1日で削除されてくれないため、Lambdaを定期実行することにしました。
import boto3
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    logger.info(event)

    s3client = boto3.client('s3')

    bucket = "my_bucket"
    prefix = "my_folder/folder_1/" # フォルダの指定が必要なら設定。なければ空文字。
    dryrun = False # 削除対象を確認するだけならTrue
    contents_count = 0 # 削除対象カウント
    
    marker = None
    while True:
        if marker:
            response = s3client.list_objects(Bucket=bucket, Prefix=prefix, Marker=marker)
        else:
            response = s3client.list_objects(Bucket=bucket, Prefix=prefix)

        if 'Contents' in response:
            contents = response['Contents']
            contents_count = contents_count + len(contents)

            for content in contents:
                if not dryrun:
                    logger.info("Deleting: s3://" + bucket + "/" + content['Key'])
                    s3client.delete_object(Bucket=bucket, Key=content['Key'])
                else:
                    logger.info("DryRun: s3://" + bucket + "/" + content['Key'])

        if response['IsTruncated']:
            marker = response['Contents'][-1]['Key']
        else:
            break

    logger.info(contents_count)
Python Lambdaを作成します。
ロールにはS3とCloudWatch Logへのアクセス権を付与します。

削除のコードは下記記事を参考にしました。


メモリやタイムアウトは削除対象ファイルの量に合わせて調整します。 テスト実行で想定通りの動きなら、CloudWatch Eventsのルールを設定して定期実行します。
cron式はUTCなのでJSTで考えるときは+9時間しましょう。

※追記
フォルダの一括削除はこちらの実装でもよさそう。