S3の削除関連のライフサイクル設定を完全に理解する

S3のコスト最適化のためにライフサイクルについて色々調べていたところ、削除マーカー周りの設定が色々あってそれぞれがどういう設定なのか整理にかなり時間がかかりました。

ようやく完全に理解したので、ここで整理しておきます。
以下のオプションの下3つについてどう設定したらどういう挙動になるのかを理解できるようになるのがゴールです。
間違いがあれば教えてください。

最後に、terraformでの設定がどう対応しているかも記載します。

目次

バージョニングと削除マーカーの関係

ライフサイクルのそれぞれの設定について見ていく前に、そもそもバージョニングと削除マーカーとの関係性を軽くおさらいしておきます。

バージョニングが有効になっていない場合にオブジェクトを削除するとそのオブジェクトは完全に削除されます。
一方で、バージョニングが有効な場合にオブジェクトを削除しても、削除マーカーが付与されるだけでオブジェクトそのものは完全に削除されません。つまり復元可能な状態として残っていることになります。

この場合、削除マーカーが最も新しいバージョンとなるため、
削除マーカーが現行バージョンとなり、オブジェクトの中身自体は非現行バージョンとなります

ここが非常に重要で、図で表すとこんな感じです。

https://docs.aws.amazon.com/AmazonS3/latest/userguide/DeletingObjectVersions.html

オブジェクト自体が残ったままということは当然、ストレージ料金もかかります。
そのためコスト最適化の観点からは、バージョニング有効化状態においては削除マーカー付与ではなく完全に削除することが重要となってきます。

そのような設定をするために、以下で詳しく見ていきます。

削除関連のライフサイクルの各設定の意味

ライフサイクルにおいて削除に関連するオプションは以下の3つです。

  1. オブジェクトの現行バージョンを有効期限切れにする
  2. オブジェクトの非現行バージョンを完全に削除
  3. 有効期限切れのオブジェクト削除マーカーまたは不完全なマルチパートアップロードを削除

それぞれを詳しく見ていきます。

1. オブジェクトの現行バージョンを有効期限切れにする

これは一番わかりやすく、特定の日数経過後にオブジェクトを削除するというものです。

この時バージョニングが有効ではない場合は完全に削除され、バージョニングが有効な場合は削除マーカーが付与されます。

残りの2つの設定はバージョニングが有効な場合のみ関係するものです。
つまり、バージョニングが有効ではない場合は、この項目のみ気にしておけばよいです。

2. オブジェクトの非現行バージョンを完全に削除

オブジェクトが現行バージョンでなくなった場合、設定した日数後に完全に削除するための設定です。

つまりこの設定を先ほどの「1. オブジェクトの現行バージョンを有効期限切れにする」と合わせると、
特定の日数経過後に削除マーカーを付与し、その数日後に完全に削除
という挙動にすることができます

逆に言えば、バージョニング有効化で1のみを設定して2を設定しない場合は削除マーカー付きのオブジェクトが存在し続けるためストレージ料金はその分加算されてしまうということに注意です。

このオプションはあくまで非現行バージョンが対象なので、削除マーカーを付与した場合に限らずバージョンがいくつかある場合はそれらの非現行バージョンが完全削除の対象になります。

また、日数だけでなく、保持するバージョンの数を指定することもできます。

3. 有効期限切れのオブジェクト削除マーカーまたは不完全なマルチパートアップロードを削除

有効期限切れのオブジェクト削除マーカーを削除

削除マーカーだけが残ったオブジェクトを削除するための設定です。設定値は有効にするか無効にするかのbooleanです。

削除マーカーが付与された場合は削除マーカーが現行バージョンになるため、先ほどの「2. オブジェクトの非現行バージョンを完全に削除」の設定で削除されるのはあくまで元々のオブジェクトになります。

そのため2の設定が適用された後は削除マーカーだけが残った状態になります。
この状態のオブジェクトを「期限切れオブジェクト削除マーカー」と言います。

つまり、削除マーカーだけが残った状態のものをクリーンアップするのがこの設定の役割です。

不完全なマルチパートアップロードを削除

巨大なファイルをアップロードするときに「Multipart Uploads」を有効にした場合、複数パーツに分けてアップロードされるらしいです。それらが全て完全に揃って1つのオブジェクトを形成するので、不完全なものがいると無駄なストレージ料金がかかって残り続けてしまうため、この設定でそういったものを削除できるらしいです。(使ったことはないです)

設定同士の競合と回避方法

さて、各設定の内容を踏まえると、たとえばバージョニング有効化のバケットにおいて
「2日後に削除マーカーを付与し、その1週間後に削除マーカー含めて完全に削除する」
ということを達成しようとした場合、一見以下のように設定すればよさそうに思えます

  1. オブジェクトの現行バージョンを有効期限切れにする: 2日
  2. オブジェクトの非現行バージョンを完全に削除: 7日
  3. 有効期限切れのオブジェクト削除マーカーを削除: 有効

しかし、実はこれは設定できません
理由は1と3の設定を同時に行うことができないからです

つまり、1つのライフサイクル設定で同時に設定できるのは1と2もしくは2と3ということになります
前者の設定では削除マーカーが残り続ける、後者の設定では自動で削除マーカーが付与されない
ということになってしまいます

回避方法としては、1と2を設定したライフサイクルと3のライフサイクルを別々で用意することです
(わざわざ「1つのライフサイクル設定で」と書いたのはそういう理由です)

公式ドキュメントにもそのように書いてあります

Note

You cannot specify both a Days and an ExpiredObjectDeleteMarker tag on the same rule. When you specify the Days tag, Amazon S3 automatically performs ExpiredObjectDeleteMarker cleanup when the delete markers are old enough to satisfy the age criteria. To clean up delete markers as soon as they become the only version, create a separate rule with only the ExpiredObjectDeleteMarker tag.

https://docs.aws.amazon.com/AmazonS3/latest/userguide/lifecycle-configuration-examples.html#lifecycle-config-conceptual-ex7

Terraformでの設定

これらの設定項目とterraformでの設定を対応させると以下のようになります

expiration {
  // 1. オブジェクトの現行バージョンを有効期限切れにする
  days                         = 2
  // 3. 有効期限切れのオブジェクト削除マーカーを削除
  expired_object_delete_marker = true
}

noncurrent_version_expiration {
  // 2. オブジェクトの非現行バージョンを完全に削除
  noncurrent_days = 7
}

先ほど見たように1と3は1つのライフサイクルでは共存できません
Terraformのドキュメントを見ても、expired_object_delete_markerの説明にConflicts with date and days と書いてあります

両方設定していた場合、これはエラーにはならずに「1. オブジェクトの現行バージョンを有効期限切れにする」の方が優先して設定されます

「3. 有効期限切れのオブジェクト削除マーカーを削除」を設定したつもりでいたのに設定できてなかったということになりかねないので、個人的にはこれはエラーにして欲しいなと思いコードを見に行ったんですが、どうやらterraformのaws-providerというよりaws-sdk-goの方のバリデーションが設定されていなさそうでした

修正すべき場所はわかったんですが、smithy-goでgenerateしてるらしく直接変更できなさそうでした
この辺の建て付けがどうなってるか分からず、めんどくなってそれ以上追うのやめました()

この辺はどこかのタイミングでちゃんと調査してみようと思います

ライフサイクル適用までのタイムラグ

ライフサイクルを設定したのに適用されていないという場合、タイムラグが考慮できていない可能性があります。

ライフサイクルの適用は設定した日数が経過した後の次の0:00(UTC)、つまり日数経過後の次の朝9:00(JST)に実行されるようです

Amazon Web Services, Inc.
Amazon S3 ライフサイクルルールに遅延がある理由 Amazon Simple Storage Service (Amazon S3) バケットにライフサイクル設定ルールを設定して、オブジェクトを別のストレージクラスに移行するか、オブジェクトを期限切れに...

たとえば、1/1の12:00に削除マーカーが付与されたオブジェクトに対して、「オブジェクトの非現行バージョンを完全に削除」の日数を1日にしていた場合は、1/2の12:00に条件を満たすことになるので実際にこの設定が適用されるのは1/3の9:00(JST)ということになります

まとめ

バージョニング有効化でライフサイクルによってオブジェクトを完全に削除するためにはいくつかの設定を組み合わせる必要がある

オブジェクトの現行バージョンを有効期限切れにする: 数日後に削除するための設定
オブジェクトの非現行バージョンを完全に削除: 削除マーカー含めて非現行バージョンとなったオブジェクトを完全に削除するための設定
有効期限切れのオブジェクト削除マーカーを削除: 削除マーカーだけが残ったオブジェクトを削除するための設定

この記事が参考になったからコーヒーくらいおごってもいいぜという方は、以下からサポートいただけると次の記事書くモチベになりますのでよろしくお願いします

Buy Me A Coffee

参考

あわせて読みたい
Deleting object versions from a versioning-enabled bucket - Amazon Simple Storage Service Delete an object in a versioning-enabled bucket by including the specific version ID of the object.
あわせて読みたい
Examples of S3 Lifecycle configuration - Amazon Simple Storage Service Examples showing how to use S3 Lifecycle configurations.
Amazon Web Services, Inc.
Amazon S3 ライフサイクルルールに遅延がある理由 Amazon Simple Storage Service (Amazon S3) バケットにライフサイクル設定ルールを設定して、オブジェクトを別のストレージクラスに移行するか、オブジェクトを期限切れに...
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次