Amazon S3 のフォルダを作成していたつもりがオブジェクトだった件

こんにちは。SCSKの谷です。

AWSマネジメントコンソールから Amazon S3 のフォルダを作成した場合、実態はフォルダではなくオブジェクトとして取り扱われることをご存じでしょうか。

本記事では、S3のフォルダがオブジェクトとして扱われてしまう場合とそうでない場合について、検証・解説していきたいと思います!

はじめに結論

AWS公式ドキュメントによると

AWS公式のドキュメントに以下の記載がありました。(以下引用)

重要

Amazon S3 コンソールでフォルダを作成すると、S3 は 0 バイトのオブジェクトを作成します。このオブジェクトキーには、指定したフォルダ名と末尾のスラッシュ (/) 文字が設定されます。例えば、Amazon S3 コンソールで、バケットに photos という名前のフォルダを作成した場合、Amazon S3 コンソールは photos/ キーを使用して 0 バイトのオブジェクトを作成します。コンソールは、フォルダの考え方をサポートするために、このオブジェクトを作成します。

引用:https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/using-folders.html

上記の通り、コンソール画面からフォルダを作成すると、そのフォルダ自体が0バイトのオブジェクトとして扱われるようです。
一方、AWS CLIなどでS3に「folder/test/test.txt」のようなファイルをアップロードする場合(例えば”aws s3 cp test.txt s3://<バケット名>/folder/test/test.txt”のようなコマンド)、プレフィックスとして指定した「folder/test/」はオブジェクトとしては扱われないようです。

フォルダがオブジェクトになる場合とならない場合について、いろいろなパターンで検証していきます!

 

検証

コンソールからS3フォルダを作成してオブジェクトを配置した場合

まずはS3のフォルダがオブジェクトとして扱われる場合についてです。

S3のコンソールよりフォルダの作成を行いました。作成したフォルダは「folder/test/」です。

上記フォルダ内に「test.txt」ファイルをアップロードし、CLIコマンド”s3 ls”で対象のS3ファイルの中を確認してみます。

結果として、「folder/test/test.txt」オブジェクトに加えて、「folder/」と「folder/test/」の末尾が”/”でフォルダとして扱われるものについても容量0のオブジェクトとして表示されていることが確認できました。
※「–recursive」オプションをつけることで各フォルダの中も再帰的に表示しています。
※「folder/」などの左にある数字がそのオブジェクトの容量を表しています。

CLIからプレフィックス指定してオブジェクトを配置した場合

次にCLIからプレフィックスを指定して、コマンドでオブジェクトを配置した場合についてみていきます。

今回指定するプレフィックスは「cli_folder/test/」とし、以下コマンドで「cli_test.txt」ファイルを先ほどと同様のS3に配置します。

aws s3 cp cli_test.txt s3://s3b-tani-test/cli_folder/test/cli_test.txt

同様にs3 lsで対象S3の中を見てみます。

先ほどとは異なり「cli_folder/test/cli_test.txt」オブジェクトのみ追加されています。
「cli_folder/」や「cli_folder/test/」がフォルダとして(容量0のオブジェクトとして)追加されることはありませんでした。

上記の検証より、コンソールでフォルダを作成した場合に限りフォルダが容量0のオブジェクトとして作成されてしまうようです。
CLIからオブジェクトを配置した場合はプレフィックスとして扱われ、フォルダとして扱われるわけではないことが確認できました。

<おまけ>CLIから末尾”/”のオブジェクトをS3に配置した場合

以下コマンドでCLIからS3に対して末尾”/”のオブジェクトを作成してみます。
(–keyオプションでオブジェクトの名前を指定できます。今回は末尾に”/”のついたオブジェクトを作成します。)

aws s3api put-object --bucket <バケット名> --key 'cli_dir/'

この場合、作成したオブジェクトがどのように扱われるかを、同様に”s3 ls”コマンドで確認してみます。

CLIから末尾”/”のオブジェクトを作成した場合もコンソールからフォルダを作成した場合と同様に、容量0のオブジェクトとして扱われるようです。

コンソールで作成したときと同様の扱いになることから、コンソール上ではフォルダとして表示されていました!

末尾”/”のオブジェクトがフォルダ扱いになることに関してはAWS公式のドキュメントにも記載がありました。

また、末尾にスラッシュ文字 (/) を含む名前が付いている既存のオブジェクトは、Amazon S3 コンソールにフォルダとして表示されます。例えば、キー名 examplekeyname/ のオブジェクトは、Amazon S3 コンソールのフォルダとして表示され、オブジェクトとしては表示されません。それ以外の場合は、他のオブジェクトと同様に動作し、AWS Command Line Interface (AWS CLI)、AWS SDK、または REST API を使用して表示および操作できます。さらに、キー名の末尾がスラッシュ文字 (/) のオブジェクトは、Amazon S3 コンソールを使用してアップロードすることができません。ただし、名前の末尾がスラッシュ (/) 文字のオブジェクトは、AWS Command Line Interface (AWS CLI)、AWS SDK、または REST API を使用してアップロードできます。

引用:https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/using-folders.html

 

<おまけのおまけ>–bodyオプションをつけた場合

–bodyオプションをつけることで、作成するオブジェクトの中身を指定することができます。
◆以下コマンド例

aws s3api put-object --bucket <バケット名> --key 'cli_dir2/' --body cli_test.txt

上記コマンドを実行した場合の結果について確認してきます。

“s3 ls”コマンドで確認したところ、末尾に”/”がついていてフォルダのように見えるにも関わらず、35バイトの容量を持ったものとして表示されていました。
今までと違い0バイトのフォルダではないのはどういうことかと思いコンソールで確認してみると、「cli_der2/」というフォルダは作成されていましたが、そのフォルダ内にファイル名「/」のファイルが作成されていました。

「/」という容量のあるオブジェクトが保存されていたので、「cli_dir2/」に容量があったのも理解はできます。
しかし、フォルダなのかオブジェクトなのか非常に紛らわしいため、実際の運用では末尾に”/”を付けたオブジェクトを作成することはやめたほうがよさそうですね。

ちなみに「/」というファイルをS3からダウンロードして中身を確認してみたところ、–bodyオプションで指定したファイルと同様の内容が記載されていたので、アップロード時にファイルが壊れたりということもなさそうです。

 

まとめ

コンソールで作成したS3フォルダがオブジェクトとして扱われる件について調査・検証しました。

公式ドキュメントに記載のある通り、コンソールからフォルダを作成した場合は容量0のオブジェクトとして扱われ、CLIからプレフィックス指定した場合はフォルダがオブジェクトとして扱われないことが確認できました。

また、”s3api put-object”コマンドを使用して末尾が”/”のオブジェクトを作成した場合、コンソールからフォルダを作成したときと同様に容量0のオブジェクトとなることが分かりました。

S3のオブジェクトをSDKで参照するLambdaスクリプト実装時などに、フォルダがオブジェクトとして扱われていることを考慮してスクリプト実装する必要があるかもしれないですね。

著者について

AWS歴3年 まだまだ勉強中のエンジニア

Junya Taniをフォローする

クラウドに強いによるエンジニアブログです。

SCSKクラウドサービス(AWS)は、企業価値の向上につながるAWS 導入を全面支援するオールインワンサービスです。AWS最上位パートナーとして、多種多様な業界のシステム構築実績を持つSCSKが、お客様のDX推進を強力にサポートします。

AWSクラウド
シェアする
タイトルとURLをコピーしました