S3用のAWS CLIコマンド、s3 と s3api についてできることの違いを調べてみた

2023.04.04

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

事業本部 Delivery 部のアベシです。
S3のAWS CLIコマンドにs3コマンド以外にもs3apiというコマンドがあることを知りましたので、s3コマンドと比べてできる事の違いを実際に使いながら調べてみました。

s3 と s3api の違い

s3 コマンドと s3api コマンドの違いですが以下のようになります。

s3

AWS の公式ドキュメントの中でこちらは高レベル (S3) コマンドと呼ばれています。 s3 コマンドは、バケットやオブジェクトの作成削除などの一般的な操作を容易に実行するためのコマンドとなるようです。

s3api

s3コマンドに対してこちらはAWSのドキュメント内でAPI レベル (s3api) コマンドと呼ばれています。 s3コマンドでできる操作も可能ですが、s3コマンドでカバーしていない S3 の API 操作についても実行可能です。S3のAPIで可能ことが実行できると考えて良さそうです。 コマンドのリファレンスに使用可能なコマンドがリストされており、非常に沢山の操作が可能であることがわかります。 また、s3コマンドと同様の操作もs3apiコマンドの場合だとレスポンスの形式が異なったりするので、用途によってどちらを使うか選ぶ事ができそうです。

実行環境

項目名 バージョン
mac OS Ventura 13.2
AWS CLI 2.11.9

s3 コマンドと s3api コマンドの使用方法とレスポンスを比べてみる

代表例としてs3コマンドlsと同様の操作ができるs3apiコマンドについて比べてみます。 バケットとオブジェクトの構成はこのようになります。

test-1-*************
  ┣ test-1/
  ┃  ┗ test-1-1
  ┗ test-2/
     ┗ test-1-2

test-2-*************
  ┣ test-1/
  ┃  ┗ test-2-1
  ┗ test-2/
     ┗ test-2-2

アカウント内のバケット情報を取得する場合

バケット情報を取得してみます。

s3 コマンド

$ aws s3 ls

2023-04-04 13:49:49 test-1-*************
2023-04-04 13:49:15 test-2-*************

s3api コマンド

lsのようにバケットを表示するコマンドはaws s3api list-bucketsとなります。

$ aws s3api list-buckets

{
    "Buckets": [
        {
            "Name": "test-1-*************",
            "CreationDate": "2023-04-04T04:49:49+00:00"
        },
        {
            "Name": "test-2-*************",
            "CreationDate": "2023-04-04T04:49:15+00:00"
        }
    ],
    "Owner": {
        "DisplayName": "*************",
        "ID": "10dde0db3daea********************"
    }
}

レスポンス内容の違い

バケット自体の情報はどちらもバケット名と作成日時となりましたが、s3api コマンドではバケット所有者の情報も取得できます。
また作成日は s3 コマンドでは JST で表示されますが、s3api コマンドでは UTC で表示されます。

  • s3 コマンドの場合
    • バケット名
    • 作成日時(JST)
  • s3api コマンドの場合
    • バケット名
    • 作成日時(UTC)
    • バケット所有者の情報

レスポンス形式の違い

s3api コマンドでは JSON 形式で表示されます。

バケット内のオブジェクトの情報を取得する場合

s3 コマンド

引き続き ls を使い、lsの後にバケット名を付けます。--recursiveを付けるとプレフィックス(フォルダ)内のオブジェクトの情報も含めて取得できます。

$ aws s3 ls test-1-************* --recursive

2023-04-04 13:50:18          0 test-1/
2023-04-04 13:52:52         12 test-1/test-1-1
2023-04-04 13:50:26          0 test-2/
2023-04-04 13:53:22         12 test-2/test-1-2

s3api コマンド

s3api コマンドではlist-objects使います。その後に --bucketオプションでバケット名を指定します。

$ aws s3api list-objects --bucket test-1-*************

{
  "Contents": [
      {
          "Key": "test-1/",
          "LastModified": "2023-04-04T04:50:18+00:00",
          "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
          "Size": 0,
          "StorageClass": "STANDARD",
          "Owner": {
              "DisplayName": "",
              "ID": "10dde0db3daea********************"
          }
      },
      {
          "Key": "test-1/test-1-1",
          "LastModified": "2023-04-04T04:52:52+00:00",
          "ETag": "\"f0ef7081e1539ac00ef5b761b4fb01b3\"",
          "Size": 12,
          "StorageClass": "STANDARD",
          "Owner": {
              "DisplayName": "",
              "ID": "10dde0db3daea********************"
          }
      },
      {
          "Key": "test-2/",
          "LastModified": "2023-04-04T04:50:26+00:00",
          "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
          "Size": 0,
          "StorageClass": "STANDARD",
          "Owner": {
              "DisplayName": "",
              "ID": "10dde0db3daea********************"
          }
      },
      {
          "Key": "test-2/test-1-2",
          "LastModified": "2023-04-04T04:53:22+00:00",
          "ETag": "\"f0ef7081e1539ac00ef5b761b4fb01b3\"",
          "Size": 12,
          "StorageClass": "STANDARD",
          "Owner": {
              "DisplayName": "",
              "ID": "10dde0db3daea********************"
          }
      }
  ]
}

レスポンス内容の違い

s3 コマンドでは 3 項目のみですが、s3api コマンドではオブジェクトの情報が詳細に表示されます。
作成日は s3 コマンドでは JST で表示されますが、s3api コマンドでは UTC で表示されます。

  • s3 コマンド
    • 作成日時(JST)
    • オブジェクトサイズ
    • プレフィックス含めいたオブジェクトキー
  • s3api コマンド
    • プレフィックス含めいたオブジェクトキー
    • 作成日時(UTC)
    • ETag
    • オブジェクトサイズ
    • ストレージのクラス
    • バケット所有者の情報

レスポンス形式の違い

バケット取得の場合と同じで s3api コマンドでは JSON 形式で表示されます。

s3api コマンドの JSON 形式レスポンスを加工する

s3api コマンドのレスポンスが形式が JSON なので、jqコマンドを使って、特定の情報だけを抽出することも可能です。

$ aws s3api list-objects --bucket test-1-************* | jq '.Contents[].Key'

"test-1/"
"test-1/test-1-1"
"test-2/"
"test-2/test-1-2"

これの応用で特定の情報だけを抽出してファイルを作成することも可能です。

$ aws s3api list-objects --bucket test-1-************* | jq '.Contents[].Key' > test.txt

$ cat test.txt
"test-1/"
"test-1/test-1-1"
"test-2/"
"test-2/test-1-2"

JSON を使い慣れている方であれば、s3api コマンドのほうがレスポンスを扱いやすいかもしれません。 また、シェルスクリプトに組み込む場合にも JSON 形式の方がシンプルに対応できる印象です。

所感

s3api コマンドは、s3 コマンドと比べてより詳細な情報と項目名の記載があるので、私はどちらかというと s3api コマンドのほうがわかりやすいかなという印象です。また、レスポンスが JSON なので加工が容易にできそうです。

s3api コマンドでのみできること

非常に沢山の操作が可能ですが、例としてバケットの暗号化方式を変更してみたいと思います。
SSE-S3で暗号化しているバケットに対して、KMSキーを使った暗号化のSSE-KMSに変更してみます。 以下のコマンドを使用します。

現在の暗号化方式を確認

まずは暗号化方式の確認を以下の行います。

$ aws s3api get-bucket-encryption --bucket test-1-*************

{
  "ServerSideEncryptionConfiguration": {
      "Rules": [
        {
          "ApplyServerSideEncryptionByDefault": {
              "SSEAlgorithm": "AES256"
          }
        }
      ]
  }
}

暗号化アルゴリズムが AES256 であることが確認できました。SSE-S3は暗号化アルゴリズムにAES256を使用しているためのこのように表示されます。

暗号化方式を変更

KMSで暗号化キーを作成してから以下のコマンドで暗号化の方法を変更します。

$ aws s3api put-bucket-encryption \
--bucket test-1-************* \
--server-side-encryption-configuration '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms","KMSMasterKeyID":"0f26e7f4-5bc5-4b39-a3e0-*************"},"BucketKeyEnabled":true}]}'

変更後の暗号化方式を確認

もう一度暗号化方式を確認してみます。

$ aws s3api get-bucket-encryption --bucket test-1-*************

{
    "ServerSideEncryptionConfiguration": {
        "Rules": [
            {
                "ApplyServerSideEncryptionByDefault": {
                    "SSEAlgorithm": "aws:kms",
                    "KMSMasterKeyID": "0f26e7f4-5bc5-4b39-a3e0-*************"
                },
                "BucketKeyEnabled": true
            }
        ]
    }
}

アルゴリズムの項目がaws:kmsとなっており、SSE-KMSの暗号化に切り替わってる事が確認できました。 以上のように、s3api コマンドを使えばCLIからも暗号化方式を変更できます。

以上。