まくろぐ

AWS S3 をコマンドライン (CLI) で操作する

更新:
作成:

AWS CLI で S3 バケットの操作を行う場合、大きく分けて以下の 2 種類のコマンドがあります。

  • aws s3 … 高レベルコマンド
  • aws s3api … API レベルコマンド

基本的には、aws s3 コマンドでカバーできない操作が出てきたときに aws s3api コマンドの方を調べてみるというやり方でいいと思います。 aws s3 コマンドの方は、OS のコマンドラインシェルのファイル操作コマンドのような体系になっています(aws s3 ls とか aws s3 rm とか)。

S3 バケットを作成する (s3 mb)

$ aws s3 mb s3://<バケット名>
実行例
$ aws s3 mb s3://makutemp-123456789012-bucket-1
make_bucket: makutemp-123456789012-bucket-1
☝️ 同名バケットの再生成でエラー

バケットの削除後に、同名のバケットを再生成しようとすると、次のような conflicting conditional operation のエラーになることがあります。 この場合は、バケットの削除処理が完了するまでしばらく待つ必要があります。

make_bucket failed: s3://makutemp-123456789012-bucket-1 An error occurred (OperationAborted) when calling the CreateBucket operation: A conflicting conditional operation is currently in progress against this resource. Please try again.

このような待ち時間を防ぐためには、s3 rb でバケットを削除した後で再生成するのではなく、s3 rm --recursive でバケット内のオブジェクトだけをすべて削除します。

S3 バケットの作成先リージョンを明示するには、--region オプションを使用します。

例: 日本のリージョンを指定
$ aws s3 mb s3://makutemp-123456789012-bucket-1 --region ap-northeast-1

参考: S3 バケットのリージョンを確認する

S3 バケットの一覧、オブジェクトの一覧を表示する (s3 ls)

S3 バケットの一覧を取得

$ aws s3 ls
実行例
$ aws s3 ls
2021-02-18 04:43:42 makutemp-123456789012-bucket-1
2021-02-19 05:14:48 makutemp-123456789012-bucket-2
2021-02-20 19:32:05 makutemp-123456789012-bucket-3

バケットに含まれるオブジェクトの一覧を取得

$ aws s3 ls s3://<バケット名>
例: バケット内のファイルを取得
$ aws s3 ls s3://makutemp-123456789012-bucket-1
2021-03-03 21:13:55        213 sample1.txt
2021-03-03 21:14:30        593 sample2.txt
2021-03-03 21:15:13        477 sample3.txt
例: 指定したディレクトリ内のファイルを取得
$ aws s3 ls s3://makutemp-123456789012-bucket-1/dir/
2021-03-03 19:13:55         53 hoge1.txt
2021-03-03 19:14:30         37 hoge2.txt

ディレクトリ名まで指定する場合は、dir/ のように最後のスラッシュが必要です。 これを付けないと、dir というファイルを探してしまいます。

例: 深いディレクトリのファイルまですべて取得
$ aws s3 ls s3://makutemp-123456789012-bucket-1 --recursive
2021-03-03 19:13:55         53 dir/hoge1.txt
2021-03-03 19:14:30         37 dir/hoge2.txt
2021-03-03 21:13:55        213 sample1.txt
2021-03-03 21:14:30        593 sample2.txt
2021-03-03 21:15:13        477 sample3.txt

オブジェクトをコピーする (s3 copy)

$ aws s3 cp <source> <target> [--options]
例: ローカルの sample.txt を my-bucket にアップロード
$ aws s3 cp sample.txt s3://my-bucket
例: my-bucket 内のファイルをダウンロード
$ aws s3 cp s3://my-bucket/sample.txt ./
例: bucket-1 内のファイルを bucket-2 にコピー
$ aws s3 cp s3://bucket-1/sample.txt s3://bucket-2
例: bucket-1 内のファイルを bucket-2/dir/ 以下にコピー
$ aws s3 cp s3://bucket-1/sample.txt s3://bucket-2/dir/
例: bucket-1 内のすべてのファイルを bucket-2 にコピー
$ aws s3 cp s3://bucket-1 s3://bucket-2 --recursive

ディレクトリの内容を同期する (s3 sync)

$ aws s3 sync <LocalDir> <S3Uri>
$ aws s3 sync <S3Uri> <LocalDir>
$ aws s3 sync <S3Uri> <S3Uri>

s3 sync コマンドは、2 回目以降の実行では更新されたファイルのみを転送します。 似たようなコマンドに s3 cp --recursive がありますが、すでに存在するファイルもすべて転送してしまうので効率が悪いです。

例: ローカルディレクトリ → S3 バケット
$ aws s3 photos s3://mybucket/photos
例: S3 バケット → ローカルディレクトリ
$ aws s3 sync s3://mybucket/photos photos
例: 同期元に存在しないファイルを同期先から削除
$ aws s3 sync photos s3://mybucket/photos --delete
$ aws s3 sync s3://mybucket/photos photos --delete
例: 同期対象外にするファイルのパターンを指定
$ aws s3 sync . s3://mybucket/myapp --exclude "*.zip"
$ aws s3 sync . s3://mybucket/myapp --exclude "*node_modules/*" --exclude "*test/*"

注意点としては、深い階層にあるファイルにマッチさせるためには、*hello.txt のように先頭に * を付ける必要があるというところです。 つまり、ほとんどのケースでは * プレフィックスを付ける必要があります。 あと、*/hello.txt のようなスラッシュ付きのプレフィックスを付けてしまうと、最上位にあるファイルにマッチしなくなってしまうようです。 ちょっと使いにくいコマンド仕様ですね。。。

オブジェクトを削除する (s3 rm)

$ aws s3 rm s3://<バケット名>/<オブジェクト名>
例: バケット内のファイルを 1 つ削除
$ aws s3 rm s3://my-bucket/sample1.txt
例: ディレクトリ以下をすべて削除
$ aws s3 rm s3://my-bucket/dir/ --recursive
例: バケット内のファイルをすべて削除(バケットを空にする)
$ aws s3 rm s3://my-bucket --recursive

バケットのバージョニングが有効になっている場合は、バケットの中身を空にすることはできません。

バケットを削除する

バージョニング設定が無効であれば、下記のコマンドでバケットを削除することができます。

$ aws s3 rb s3://<バケット名>

ただし、空ではないバケット(オブジェクトを含むバケット)を削除しようとすると、BucketNotEmpty というエラーが発生します。

例: バケット削除エラー
$ aws s3 rb s3://my-bucket

remove_bucket failed: s3://my-bucket An error occurred (BucketNotEmpty)
when calling the DeleteBucket operation: The bucket you tried to delete
is not empty

含まれているオブジェクトもすべて削除してしまってよい場合は、バケット削除時に --force オプションを使用します。 S3 Glacier ストレージクラスに移行済みのオブジェクトも含めて、オブジェクトがすべて削除されます。

例: 中のオブジェクトを含めてバケットを削除
$ aws s3 rb s3://my-bucket --force

バケットのタグ関連の操作

バケットのタグを取得する (s3api get-bucket-tagging)

$ aws s3api get-bucket-tagging --bucket <バケット名>
$ aws s3api get-bucket-tagging --bucket bucket-123456789012-hello
TagSet:
- Key: DeploySlot
  Value: prod
- Key: Department
  Value: Marketing
- Key: CostCenter
  Value: 1234ABCD

バケットにタグを設定する (s3api put-bucket-tagging)

$ aws s3api put-bucket-tagging --bucket <バケット名> --tagging=<タグセット>

次の例では、2 つのタグを S3 バケットにセットしています。 既存のタグは上書きされてしまうことに注意してください。

実行例
$ aws s3api put-bucket-tagging --bucket bucket-123456789012-hello
    --tagging "TagSet=[{Key=key1,Value=val1},{Key=key2,Value=val2}]"

JSON ファイルでタグの内容を記述しておいて、それを --tagging オプションで渡すこともできます。

実行例
$ aws s3api put-bucket-tagging --bucket bucket-123456789012-hello \
    --tagging file://tagging.json
{
  "TagSet": [
    {"Key": "key1", "Value": "val1"},
    {"Key": "key2", "Value": "val2"},
    {"Key": "key3", "Value": "val3"}
  ]
}

バケットのバージョニング (s3api put-bucket-versioning)

バケットのバージョニングを有効にすると、S3 バケットに同名のキーでファイルをアップロードしたときに、過去のバージョンが残るようになります。

具体的には、バージョニング有効時にファイルをアップロードすると、そのオブジェクトに一意の バージョン ID が割り当てられて、過去のファイルと区別できるようになります。 バージョニング無効時にアップロードされたファイルのバージョン ID は null になります。

キーバージョン ID説明
hello.txt8PqtjVIxmjtn_aJ3aVxAJHVxOWNdWlXk3 回目のアップロード(バージョニング有効時)
hello.txt2vE4HOEHRPPd5hSqAazAHQczmQnmmlQ72 回目のアップロード(バージョニング有効時)
hello.txtnull1 回目のアップロード(バージョニング無効時)
例: バージョニングを有効にする
$ aws s3api put-bucket-versioning --bucket mybucket \
    --versioning-configuration Status=Enabled
例: バージョニングを無効にする
$ aws s3api put-bucket-versioning --bucket mybucket \
    --versioning-configuration Status=Suspended

バージョニングを無効に切り替えても、バージョニング有効時にアップロードしたファイル群が消えることはありません。 新しくアップロードされるファイルのバージョン ID が null になるだけです。 このとき、バージョン ID が null のオブジェクトが既に存在する場合は上書きされます(過去にバージョニング無効時にアップロードしたものがある場合)。

各バージョンのファイルは、S3 のマネージメントコンソールから個別に削除することができます。

バケットのリージョンを確認する (s3api get-bucket-location)

S3 バケットがどのリージョンに作成されているかを調べるには以下のようにします。

$ aws s3api get-bucket-location --bucket <バケット名>
実行例
$ aws s3api get-bucket-location --bucket makutemp-123456789012-bucket-1
LocationConstraint: ap-northeast-1

このコマンドでは、バケット名に s3:// プレフィックスは付けてはいけないことに注意してください。 バケット名やバケットの ARN を指定します。

出力のフォーマットは、設定によって JSON 形式だったり YAML 形式だったりします。 上記の例は、YAML 形式です。

関連記事

まくろぐ
サイトマップまくへのメッセージ