はじめに
Amazon S3のライフサイクルルールで、「期限切れのオブジェクト削除マーカーを削除する」設定を行ったにも関わらず、有効期限が切れたはずの削除マーカーがいつまでも残ってしまい、困っていませんか?その原因は、ライフサイクルルールで「最小オブジェクトサイズ」を指定していることにあるのかもしれません。トラブル事例を基に解説します。
経緯
お客様より、「ライフサイクルルールを設定しているS3バケットについて、有効期限切れの削除マーカーが消えていません。」という問い合わせを受けたため、調査することになりました。
お客様のライフサイクルルール
お客様のライフサイクルルールには、以下2つのルールがバケットに設定されており、期待したとおりの動作とはなっていませんでした。
| ルール名 | 設定内容 | 期待している動作 | 事例での実際の動作 |
|---|---|---|---|
| ルールA | 最少オブジェクトサイズ:0を設定 | 「非現行バージョンの削除マーカー」の削除 | 削除されない(※1) |
| ルールB | 期限切れの削除マーカーを削除する | 「期限切れの削除マーカー」の削除 | 削除マーカーが期限切れにならない(※2) |
事例での実際の動作、となってしまった原因
※1:0バイトの「削除マーカー」はライフサイクルルールの対象に含まれない
※2:※1により、いつまでも複数バージョンの削除マーカーが存在し続けることになったため、削除マーカーが期限切れにならなかった
もう少し、詳しく解説
・ルールスコープのフィルターで、「最小オブジェクトサイズ」を指定した場合の動作
⇒ 最小オブジェクトサイズを指定すると「削除マーカー」はライフサイクルルールの対象に含まれません。
※削除マーカーのオブジェクトサイズは 0 バイトなので、「最小オブジェクトサイズ:0」にすれば問題ないように見えますが、最小オブジェクトサイズに指定された値は含まれず、それより大きい値が対象となります。つまり、最小オブジェクトサイズを指定すると0バイトのオブジェクトはライフサイクルルールの対象から除外されます。
ObjectSizeGreaterThan フィルターおよび ObjectSizeLessThan フィルターは、指定された値を除外します。例えば、S3 Standard ストレージクラスから S3 Standard-IA ストレージクラスに移動するためにオブジェクトのサイズを 128 KB から 1024 KB に設定した場合、1024 KB ちょうどのオブジェクトと 128 KB ちょうどのオブジェクトは S3 Standard-IA に移動されません。代わりに、このルールは 128 KB より大きく 1024 KB よりも小さいサイズのオブジェクトにのみ適用されます。
・「期限切れの削除マーカー」とは
⇒ 単に設定した期限を過ぎただけでなく、すべてのオブジェクトバージョンが削除され、単一の削除マーカーだけが残っている場合のマーカーです。
期限切れのオブジェクト削除マーカーは、すべてのオブジェクトバージョンが削除され、単一の削除マーカーだけが残っている場合のマーカーです。
上記を踏まえると、複数バージョンの削除マーカーがある場合は以下のような挙動になります。
1.ルールAの「最小オブジェクトサイズ」の指定により、非現行バージョンの削除マーカーが削除されません。
2.1.により、現行バージョンの削除マーカーが「単一の削除マーカーだけが残っている」状態にならないため、期限切れの削除マーカーにはなりません。つまり、ルールBが実行されません。
そのため、いつまでも削除マーカーが残り続ける事になります。
■必要な対処
0バイトのオブジェクトである削除マーカーが削除されるようにする必要があります。
⇒ ルールAのルールスコープで、フィルターを使用せず、「バケット内のすべてのオブジェクトに適用」を設定します。
検証1
比較のために、二つのバケットを作成し、ライフサイクルルールの設定で、一方は「最小オブジェクトサイズ:0」を指定し、もう一方は「バケット内のすべてのオブジェクトに適用」を選択、それ以外は全て同じ設定にします。
◇以下の内容で作成
・バケット①:lfc-test-1
・lfc-test-1のライフサイクルルール:lfc-test-1-rule-A、lfc-test-1-rule-B
・バケット②:lfc-test-2
・lfc-test-2のライフサイクルルール:lfc-test-2-rule-A、lfc-test-2-rule-B
■lfc-test-1-rule-A:最少オブジェクトサイズ:0を設定


■lfc-test-2-rule-A:「バケット内のすべてのオブジェクトに適用を選択」、それ以外はlfc-test-1-rule-Aと同じ内容で設定

■lfc-test-2-rule-B:lfc-test-1-rule-Bと同じ内容で設定
■S3コンソールから、それぞれのバケット内にフォルダを二つ作成し、片方のフォルダにはファイルを格納し、もう片方は空のままにしておきます。
■作成したバケットの内容を表示すると、以下のようになります。

■結果(途中経過は省きます)
〇バケット:lfc-test-1
配下のフォルダは現行バージョンのまま残ってしまいました。フォルダ内のファイルは現行/非現行バージョンともに削除されており、削除マーカーも削除されています。


〇バケット:lfc-test-2
削除マーカー、フォルダを含め現行/非現行バージョンの全てのオブジェクトが削除されています。

■補足:フォルダが残る理由
S3にはフォルダという概念がなく、S3 コンソールからフォルダを作成すると、末尾が「/」の0バイトのオブジェクトが作成され、その配下に3バイトのファイルを格納すると、別の3バイトのオブジェクトが作成されます。
以下のようなイメージです。

ライフサイクルルールに最小オブジェクトサイズ:0を指定すると、0バイトのオブジェクトは適用外となるため、上記の例では、TEST/AAA.txtのみ削除されます。
検証2
■次に複数バージョンの削除マーカーが作成されるように、検証1で空になった両方のバケットのフォルダ:TESTに対して以下の操作を実施します。
(1)ファイル AAA.txt をアップロード
(2)ファイル AAA.txt を削除
(3)ファイル AAA.txt (同名)をアップロード
(4)ファイル AAA.txt を削除
するとバージョン表示は以下のようになります。
名前 タイプ
AAA.txt 削除マーカー
└AAA.txt txt
└AAA.txt 削除マーカー
└AAA.txt txt
■途中経過 その1
〇バケット:lfc-test-1
最初にアップロードしたオブジェクト(txt)が削除されています。

〇バケット:lfc-test-2
最初にアップロードしたオブジェクト(txt)とその削除マーカーが削除されています。

■途中経過 その2
〇バケット:lfc-test-1
2回目にアップロードしたオブジェクト(txt)が削除されて、削除マーカーは残っています。

〇バケット:lfc-test-2
2回目にアップロードしたオブジェクト(txt)が削除されています。

■結果
〇バケット:lfc-test-1
オブジェクトの削除マーカーのみが残っている状態です。

〇バケット:lfc-test-2
全てのオブジェクトが削除されました。

■補足:ライフサイクルルールの注意点
ライフサイクルルールは設定したアクションが実際に実行されるまでには、遅延が生じる場合があります。そのため、実行されていないのかと心配になりますが、数日後に実行される場合があります。
ライフサイクルルールが満たされてから、ルールのアクションが完了するまでに遅延が生じる場合があります。例えば、ライフサイクルルールによって一連のオブジェクトの有効期限が 1 月 1 日に切れるとします。有効期限ルールは 1 月 1 日に満たされますが、Amazon S3 は数日後または数週間後までこれらのオブジェクトを実際に削除しない場合があります。この遅延は、S3 ライフサイクルがオブジェクトを移行または有効期限のためのキューに非同期的に入れるために発生します。
まとめ
S3 ライフサイクルルールに最小オブジェクトサイズ:0を指定すると、0バイトのオブジェクトも対象となるように思われますが、対象になるのは0より大きい値となります。そのため、削除マーカーやフォルダ(末尾が「/]のオブジェクト)は対象外となり、複数バージョンの削除マーカーが存在すると、単一の削除マーカーとならないため、削除マーカーが期限切れとならず、いつまでも残り続けてしまいます。
S3ライフサイクルルールは想定したとおりに動作しないことも多く、仕様が分かりにくいですが、この記事が何方かの参考になれば幸いです。

