Amazon S3のバケットライフサイクル設定でベースレベルPrefixが非推奨になっていた

こんにちは。サービスグループの武田です。S3バケットのライフサイクル設定ではPrefixの代わりにFilterを使用のが推奨になっていました。
2022.01.31

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。サービスグループの武田です。

先日S3バケットに設定しているライフサイクル設定を更新しようとしたらエラーになりました。調べてみると、従来からあるPrefixが非推奨となり、代わりにFilterを使用するようになっていました。このエントリでは具体例を紹介しながらエラー内容などを確認してみます。

バケットを作成し従来のルールを設定する

まずはサンプルとなるバケットを作成し、従来の構造でルールを設定してみます。

$ aws s3api create-bucket --bucket policy-test-123456789012 --create-bucket-configuration LocationConstraint=ap-northeast-1

$ aws s3api put-bucket-lifecycle-configuration --bucket policy-test-123456789012 --lifecycle-configuration '{
    "Rules": [
        {
            "ID": "Delete-After-1year",
            "Status": "Enabled",
            "Prefix": "",
            "Expiration": {
                "Days": 365
            }
        }
    ]
}'

この設定は成功します(2022-01-31時点)。オブジェクトが作成されてから1年後に自動的に削除される設定ですね。

ルール設定が失敗する例

さて今度は、1週間後に不完全なマルチパートアップロードを削除する設定を追加するとします。具体的には次のようなコマンドを実行してみます。

$ aws s3api put-bucket-lifecycle-configuration --bucket policy-test-123456789012 --lifecycle-configuration '{
    "Rules": [
        {
            "ID": "Delete-After-1year",
            "Status": "Enabled",
            "Prefix": "",
            "Expiration": {
                "Days": 365
            }
        },
        {
            "ID": "Delete-Incomplete-Multipart-Upload-7days",
            "Status": "Enabled",
            "Filter": {},
            "AbortIncompleteMultipartUpload": {
                "DaysAfterInitiation": 7
            }
        }
    ]
}'

このコマンドは失敗し、次のようなエラーメッセージが表示されました。

An error occurred (InvalidRequest) when calling the PutBucketLifecycleConfiguration operation: Filter element can only be used in Lifecycle V2.

私は知らなかったのですが、 Lifecycle V2 という仕様があるようですね。ちなみにルールを書く順序を逆にするとエラーメッセージが少し変わります。

$ aws s3api put-bucket-lifecycle-configuration --bucket policy-test-123456789012 --lifecycle-configuration '{
    "Rules": [
        {
            "ID": "Delete-Incomplete-Multipart-Upload-7days",
            "Status": "Enabled",
            "Filter": {},
            "AbortIncompleteMultipartUpload": {
                "DaysAfterInitiation": 7
            }
        },
        {
            "ID": "Delete-After-1year",
            "Status": "Enabled",
            "Prefix": "",
            "Expiration": {
                "Days": 365
            }
        }

    ]
}'

このコマンドを実行した際のエラーメッセージは次のものでした。

An error occurred (InvalidRequest) when calling the PutBucketLifecycleConfiguration operation: Base level prefix cannot be used in Lifecycle V2, prefixes are only supported in the Filter.

なんとなく内部処理を想像すると、指定したルールをループ処理として順番に適用していくが、最初に設定した書式によってLifecycleのバージョンが決定される。そして、以降のルールも同じバージョンで書かれていないとダメなように読み取れます。

正しい記述例

ドキュメントによるとベースレベルPrefixは This is no longer used; use Filter instead. のようです。そのため今後は使用しない方がよいでしょう。というわけで、Filterに統一し次のように記述するのがよさそうです。

$ aws s3api put-bucket-lifecycle-configuration --bucket policy-test-123456789012 --lifecycle-configuration '{
    "Rules": [
        {
            "ID": "Delete-After-1year",
            "Status": "Enabled",
            "Filter": {},
            "Expiration": {
                "Days": 365
            }
        },
        {
            "ID": "Delete-Incomplete-Multipart-Upload-7days",
            "Status": "Enabled",
            "Filter": {},
            "AbortIncompleteMultipartUpload": {
                "DaysAfterInitiation": 7
            }
        }
    ]
}'

まとめ

昔に設定したライフサイクル設定を更新する際に、新旧の書き方が混在しエラーになってしまいました。そもそもベースレベルのPrefixが非推奨になっていたことを認識していなかったことが原因です。ぜひ設定してあるライフサイクルを確認し、古い書き方であればアップデートしてあげてください。

参考URL