S3ファイルやDynamoDBレコードの自動削除


S3ファイルやDynamoDBレコードの自動削除

この記事はサーバーレスWebアプリ Mosaicを開発して得た知見を振り返り定着させるためのハンズオン記事の1つです。

以下を見てからこの記事をみるといい感じです。
* Lambda(Python) + Rekognition で顔検出

はじめに

S3やDynamoDBって、もちろん長期的に保存したい用途に利用することもありますが、一時的なデータ保存場所として利用するケースも多いですよね。ワタシのMosaicなんかも、30分くらいで消えてしまって何ら問題ありません。
そんな時は自動的に削除される仕組みがありますので、それを利用しましょう。

コンテンツ

S3ファイルの自動削除

上で「30分くらいで消えてしまって何ら問題ありません」と書きましたが、残念ながらS3からの自動削除は、最短1日からとなります。いやー、残念。

さて設定の仕方ですが、
AWSコンソール > S3 > 管理タブ > ライフサイクル > +ライフサイクルルールの追加 ボタンを押下

ルール名は適当にdelete-a-day-in-publicなどと付けました。
今回はpublicフォルダの中だけを対象にしたいのでpublic/のようなプレフィックスを追加します。

次に進んで、ライフサイクルルールは、削除しますので全てチェックOFFのままとします。

次の「失効の設定」は全てチェックONにして、日数を入力します。ここでは1日で消えるようにしました。

で、最後確認して、保存してください。
ライフサイクルの一覧に追加されていますね。

S3のファイルを最短1日で自動的に削除するための設定は以上です。

DynamoDBレコードの自動削除

続いてDynamoDBです。
DynamoDBは秒単位で削除される日時を指定できます。これなら「30分くらいで消えてしまって何ら問題ありません」が実現できますね!と思いきやざーんねん。最大48時間のタイムラグがあるとか。なんだそりゃって感じですよね。
運が良ければ30分、運が悪くても最大48時間30分で、自動的にレコードを削除することはできるということです。

そしてDynamoDBは、S3のようにコンソールをポチポチやったら設定できるというわけではありません。
自動的に削除される時間を入れるためのフィールド(列)が必要となります。
つまり、その列にレコードを入れる際に、削除される時間を毎回設定する必要があるということです。
ちょっと面倒ですよね。

さてサンプルプログラムの方から削除用のフィールドに値をいれてゆきましょう。
DynamoDBへレコードを挿入するのはAppSync経由ですので、そこにフィールドを追加することになります。

AWSコンソール > AppSync > Sample appsync api > スキーマ
SchemaのCreateSampleAppsyncTableInputにInt型のdeleteTimeというフィールドを追加しておきます。

deleteTime: Intを追加したら、「スキーマを保存」ボタンを押下します。

今回のサンプルアプリは、DynamoDBへのレコード挿入はバックエンドからのみです。
従いまして、LambdaのPythonのコードを修正してゆくことになります。

lambda_function.py
  : 
import datetime
  : 
def apiCreateTable(group, path):
    logger.info("start apiCreateTable({0}, {1})".format(group, path))

    time = datetime.datetime.now()
    time = time + datetime.timedelta(minutes=30)
    epocTime = int(time.timestamp())

    try:
        query = gql("""
            mutation create {{
                createSampleAppsyncTable(input:{{
                group: \"{0}\"
                path: \"{1}\"
                deleteTime: {2}
              }}){{
                group path
              }}
            }}
            """.format(group, path, epocTime))
        _client.execute(query)
    except Exception as e:
        logger.exception(e)
        raise e
  :

deleteTimeフィールドへ指定する値ですが、「エポック秒」で指定します。
は?って感じの人も多いと思いますが、「エポック秒」とはつまり「UNIX時間」のことです。
・・・は?(怒)って感じですよね。

UNIX時間.wiki
UNIX時間(ユニックスじかん)またはUNIX時刻(ユニックスじこく、UNIX time(ユニックスタイム)、POSIX time(ポジックスタイム))とはコンピューターシステム上での時刻表現の一種。UNIXエポック、すなわち協定世界時 (UTC) での1970年1月1日午前0時0分0秒から形式的な経過秒数(すなわち、実質的な経過秒数から、その間に挿入された閏秒を引き、削除された閏秒を加えたもの)として表される。GPS時刻などとは異なり、大多数のシステムでは、本当の経過秒数を表すものではない。

さてエポック秒の詳細はほどほどにして、先ほどのプログラムを実行すると、DynamoDBのdeleteTimeフィールドに値が入っているのを確認しましょう。

この状態ではまだレコードは削除されません。DynamoDBのコンソールで、このフィールドに対して「有効期限 (TTL) 属性」の指定をする必要があります。
AWSコンソール > DynamoDB > テーブル > sample_appsync_table の概要タブで、「有効期限 (TTL) 属性」という項目が無効になっています。「TTLの管理」を選択してください。

TTL属性にフィールド名deleteTimeを設定して次へ進みます。

これで設定完了なのですが、設定が反映されるまでに最大1時間かかるようです。
しばらく待ってから、テーブルの項目を見てみましょう。反映されると、指定したdeleteTimeフィールドに(TTL)というマークが付きます。

これで、deleteTimeに指定したエポック時間(から48時間以内)にレコードが自動的に削除されます。

あとがき

不要なものはどんどん削除しましょうというお話でしたが、それが許されるのであればどんどん積極的に削除してゆくべきですね。パフォーマンスや料金的にもメリットありますし、フロントからアクセスされる画像やそのパスなどはさっさと消えてくれたほうがプライバシー保護の観点からも望ましいですよね。

しかしDynamoDBのレコードは、テーブルに対して設定できるようになってくれるともっと使いやすいと思うんですけどねぇ。アプリが気にしなくて済む日を夢見ています。