aws CLIでバケットとオブジェクトを扱う
目標
S3互換ストレージの基本操作(プロファイル、バケット、オブジェクトのアップロード、プレフィックス、一覧、ETag、コピー、メタデータ)をaws CLIで手に馴染ませ、オブジェクトストレージにディレクトリがないという事実を体感します。
なぜ重要なのか
S3 APIを理解することは、特定のベンダーを学ぶことではありません。AWS S3、SeaweedFS、Garage、Ceph RGW、MinIOがすべて同じAPIを話すので、このAPIは事実上の移植性のレイヤーです。実際に、2025–2026年にMinIOのコミュニティエディションが配布を中止したとき、アプリケーション側の移行コストが大きくなかった理由が、これです。エンドポイントと資格情報を変えるだけで、コードはおおむねそのままでした。このラボの環境も、同じことを経験しました。サーバーがMinIOからSeaweedFSのS3ゲートウェイに変わりましたが、ここで打つコマンドは、AWSでも1文字も変えずに動きます。このラボで特に覚えておくことは、ステップ6のETagです。単一パートのアップロードで、ETagは内容のmd5であり、そのため、アップロードが完全だったかを、クライアントが自分で検証できます。次のラボで、マルチパートアップロードのETagがこれとどう違うかを扱うとき、ここで見たルールが出発点になります。
ステップ
aws configure setでプロファイルlocalに、4つの値(aws_access_key_id、aws_secret_access_key、region、endpoint_url(http://127.0.0.1:9000))を入れてください。資格情報は/opt/fixtures/s3/creds.envにあります。aws --profile local s3 lsがエラーなく終わる必要があります。- バケット
lab-mediaを作成してください。aws --profile local s3 lsの一覧に現れる必要があります。 /opt/fixtures/s3/logo.pngをs3://lab-media/img/logo.pngにアップロードしてください。/opt/fixtures/s3/のbanner.pngをimg/banner.pngに、readme.txtをdoc/readme.txtに、sales.csvをdoc/sales.csvにアップロードしてください。aws --profile local s3 ls --recursive s3://lab-mediaの結果を/root/s3/list.txtに保存してください。ちょうど4行である必要があります。/root/s3/etag.txtに、etag=<값>とmd5=<값>の2行(プレースホルダーは値です)を書いてください。logo.pngのETag(引用符を除く)と、ローカルファイルのmd5が同じである必要があります。doc/readme.txtをdoc/README.txtへサーバーサイドコピーしたあと、元のオブジェクトを削除してください。aws --profile local s3 ls s3://lab-media/doc/にREADME.txtだけがあり、readme.txtはない必要があります。sales.csvをtext/csvのContent-Typeで、もう一度アップロードしてください。aws --profile local s3api head-object --bucket lab-media --key doc/sales.csvの出力のContentTypeがtext/csvである必要があります。
参考
- プロファイルの確認:
aws configure list --profile local(シークレットは末尾の4文字だけが表示されます) - 毎回
--profile localを付けたくなければ、export AWS_PROFILE=local - 再帰的な一覧:
aws s3 ls --recursive s3://lab-media - オブジェクトのメタデータ:
aws s3api head-object --bucket lab-media --key img/logo.png - Content-Typeの指定:
aws s3 cp 파일 s3://버킷/키 --content-type text/csv(プレースホルダーはファイルとバケットとキーです) aws s3は、ファイルコピーのように使う高水準のコマンドで、aws s3apiは、S3 API呼び出し1つ1つに1対1で対応します。何が実際にやり取りされるかを見たいときは、s3apiを使います。- よくあるミス1: バケット名に大文字やアンダースコアを使うこと。DNSのルールに従います。
- よくあるミス2:
img/をフォルダーと勘違いして、別に作ろうとしてしまうこと。キー名の一部にすぎません。
S3プロファイルを設定する
aws configure setでプロファイルlocalに、aws_access_key_id、aws_secret_access_key、region、endpoint_url(http://127.0.0.1:9000)の4つの値を入れてください。資格情報は/opt/fixtures/s3/creds.envにあります。aws --profile local s3 lsがエラーなく終わる必要があります。
エンドポイントと資格情報を、プロファイル1つにまとめます。資格情報は/opt/fixtures/s3/creds.envにあり、endpoint_urlを省くと、CLIが本物のAWSへ出ていこうとします。
バケットを作る
バケットlab-mediaを作成してください。aws --profile local s3 lsの一覧に現れる必要があります。
バケット名はDNSのルールに従います。小文字、数字、ハイフンだけを使えます。
オブジェクトを1つアップロードする
/opt/fixtures/s3/logo.pngをs3://lab-media/img/logo.pngにアップロードしてください。
ローカルのパスと、宛先のキーを一緒に指定します。宛先のキーのスラッシュは、フォルダーではなく、名前の一部です。
プレフィックスで整理する
/opt/fixtures/s3/のbanner.pngをimg/banner.pngに、readme.txtをdoc/readme.txtに、sales.csvをdoc/sales.csvにアップロードしてください。
img/とdoc/の下に分けてアップロードします。実際にはフォルダーが作られるのではなく、キー名がそうなるのです。
再帰的な一覧を取得する
aws --profile local s3 ls --recursive s3://lab-mediaの結果を/root/s3/list.txtに保存してください。ちょうど4行である必要があります。
既定の一覧は、プレフィックス単位で折りたたまれて見えます。すべてを展開するオプションがあります。
ETagとローカルのハッシュを比べる
/root/s3/etag.txtに、etag=<값>とmd5=<값>の2行(プレースホルダーは値です)を書いてください。logo.pngのETag(引用符を除く)と、ローカルファイルのmd5が同じである必要があります。
単一パートのアップロードのETagは、内容のmd5です。2つの値を並べて書いて、比べてください。
サーバーサイドコピーのあと、元を削除する
doc/readme.txtをdoc/README.txtへサーバーサイドコピーしたあと、元のオブジェクトを削除してください。aws --profile local s3 ls s3://lab-media/doc/にREADME.txtだけがあり、readme.txtはない必要があります。
名前の変更はありません。コピーして削除することが、名前の変更です。ダウンロードなしに、サーバーで処理されるようにしてください。
Content-Typeを指定してアップロードし、確認する
sales.csvをtext/csvのContent-Typeで、もう一度アップロードしてください。aws --profile local s3api head-object --bucket lab-media --key doc/sales.csvの出力のContentTypeがtext/csvである必要があります。
拡張子から推測されることもありますが、明示するほうが安全です。オブジェクトのメタデータを照会して確認してください。