S3の条件付き書き込みをAWSCLIで試してみた

S3の条件付き書き込みをAWSCLIで試してみた

条件付き書き込み(conditional writes)をサポートしたS3の動作について、最新バージョンのAWSCLIで確認してみました。
Clock Icon2024.08.22

2024年8月20日、
Amazon S3 が 条件付きの書き込み (conditional writes) をサポート、書き込み先のS3上にキーが重複するファイルが存在する場合、上書きを回避できるアップデートがありました。

https://aws.amazon.com/jp/about-aws/whats-new/2024/08/amazon-s3-conditional-writes/

今回、サポートされた S3の条件付き書き込みの動作を AWS CLIを利用して確認する機会がありましたので、紹介させていただきます。

準備

CloudShell

AWS CloudShellを利用して、S3の動作確認を行いました。

AWSCLI

AWS CLI バージョン「1.34.2」で S3の conditional writes のサポートを確認しました。

  {
    "category": "``s3``",
    "description": "Amazon Simple Storage Service / Features : Add support for conditional writes for PutObject and CompleteMultipartUpload APIs.",
    "type": "api-change"
  }

https://github.com/aws/aws-cli/blob/develop/.changes/1.34.2.json

AWSCLI(v1) を最新バージョンに更新しました。

curl -s "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "/tmp/awscli-bundle.zip"
unzip -q /tmp/awscli-bundle.zip -d /tmp/
sudo /usr/bin/python3 /tmp/awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
$ aws --version
aws-cli/1.34.2 Python/3.9.16 Linux/6.1.102-108.177.amzn2023.x86_64 exec-env/CloudShell botocore/1.35.2

動作確認

help

引数として 「--if-none-match」 の指定が追加されていることを確認しました。

$ aws s3api put-object help

--if-none-match (string)
    Uploads  the object only if the object key name does not already ex-
    ist in the bucket specified. Otherwise, Amazon S3 returns a 412 Pre-
    condition Failed error.

    If a conflicting operation occurs during the upload S3 returns a 409
    ConditionalRequestConflict response. On a  409  failure  you  should
    retry the upload.

    Expects the '*' (asterisk) character.

    For  more  information about conditional requests, see RFC 7232 , or
    Conditional requests in the Amazon S3 User Guide .

S3準備

テスト用のS3バケットと、put に利用するダミーファイルを用意しました。

S3_BUCKET='test-20240820'
aws s3 mb "s3://${S3_BUCKET}"
date > dummy.txt 
S3_KEY='dummy.txt'

put-object

条件付き書き込み --if-none-match "*" を利用して、ダミーファイルのアップロードを試みました。

aws s3api put-object --bucket ${S3_BUCKET} --key ${S3_KEY} --body ./dummy.txt --if-none-match "*" 

初回

$ aws s3api put-object --bucket ${S3_BUCKET} --key ${S3_KEY} --body ./dummy.txt  
{
    "ETag": "\"***\"",
    "ServerSideEncryption": "AES256"
}

2回目

条件付き書き込み指定のエラーが発生しました。

$ aws s3api put-object --bucket ${S3_BUCKET} --key ${S3_KEY} --body ./dummy.txt --if-none-match "*" 

An error occurred (PreconditionFailed) when calling the PutObject operation: At least one of the pre-conditions you specified did not hold

3回目

--if-none-match "*" を省略、条件付き書き込みを指定しない場合は、アップロードに成功しました。

$ aws s3api put-object --bucket ${S3_BUCKET} --key ${S3_KEY} --body ./dummy.txt  
{
    "ETag": "\"***\"",
    "ServerSideEncryption": "AES256"
}

4回目

重複する対象をS3から削除する事で、条件付き書き込みが有効な状態でも アップロードに成功しました。

$ aws s3 rm s3://${S3_BUCKET}/dummy.txt 
delete: s3://***-20240820/dummy.txt
$ aws s3api put-object --bucket ${S3_BUCKET} --key ${S3_KEY} --body ./dummy.txt --if-none-match "*" 
{
    "ETag": "\"***\"",
    "ServerSideEncryption": "AES256"
}

まとめ

S3を利用するシステムで、ファイルの整合性維持のため上書きを回避する必要がある場合、今回サポートされた条件付き込みと、適切な例外処理を実装する事で、シンプルな利用が可能となる可能性があります。

分散システムのノード間でS3の上書き回避するため事前にキーの重複チェックを実施していたり、S3のバージョニング情報を利用してファイルの上書き更新が発生していないことを確認していた場合、APIの実行課金の回避や、性能向上についても改善が期待出来る場合があります。

AWS SDKを最新版に更新し、S3の 条件付き書き込みを評価頂くことをお勧めします。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.