AWS CLI で S3 オブジェクトのメタデータを変更する
2020-07-29AWS CLI を使って Amazon S3 に格納されているオブジェクトのメタデータを変更します。思っていた方法と違ったので、備忘録のための書き残しておきます。
目次
TL;DR
s3api copy-object
コマンドを使うupdate-metadata
みたいなコマンドはない- 変更 (追加・削除) というよりは 上書き という感覚でやる
やってみる
AWS CLI のバージョンは、 v2 の現時点の最新バージョンで実行します。
$ aws --version
aws-cli/2.0.35 Python/3.7.4 Darwin/19.5.0 botocore/2.0.0dev39
対象のオブジェクトを追加
まずはメタデータを変更する対象となるオブジェクトを追加します。ファイルは何でも良いので、今回は下記のような JSON ファイルを追加します。
$ cat sample.json | jq .
{
"message": "AWS CLI ha iizo"
}
今回の対象バケット名は s3-metadata-test-michimani
とします。
$ aws s3 cp ./sample.json s3://s3-metadata-test-michimani/sample.json
upload: ./sample.json to s3://s3-metadata-test-michimani/sample.json
ちなみに s3
コマンドは S3 に対する API 高レベルで抽象化したコマンドで、今回のようにバケットにオブジェクトを追加したり、逆にローカルにオブジェクトをコピーしてきたりする場合には楽に使えます。
$ aws s3 help
NAME
s3 -
DESCRIPTION
This section explains prominent concepts and notations in the set of
high-level S3 commands provided.
オブジェクトの情報確認
オブジェクトの追加ができたら、現時点でのオブジェクトの情報を確認します。確認には、 s3api head-object
コマンドを使います。
$ aws s3api head-object \
--bucket s3-metadata-test-michimani \
--key sample.json
{
"AcceptRanges": "bytes",
"LastModified": "2020-07-28T22:30:41+00:00",
"ContentLength": 35,
"ETag": "\"6f1d414f6389f754c0a93fab4727f2d9\"",
"ContentType": "application/json",
"Metadata": {}
}
s3api
コマンドは先程の s3
コマンドとは違い、 S3 に対する操作を行う各 API を実行するコマンドになっています。 S3 を操作するコマンドにはもう一つ s3control
コマンドがありますが、このコマンドではバッチオペレーションやアクセスポイントに関する操作を実行することができます。
メタデータの更新
では、先程追加したオブジェクトに対してメタデータの更新 (追加・削除) を実行してみます。
なお、 AWS CLI では S3 オブジェクトに対してメタデータを更新 (追加・削除) する update-metadata
みたいなコマンドはありません。なので、 s3api copy-object
コマンドを使います。
$ aws s3api copy-object help
...
SYNOPSIS
copy-object
[--acl <value>]
--bucket <value>
[--cache-control <value>]
[--content-disposition <value>]
[--content-encoding <value>]
[--content-language <value>]
[--content-type <value>]
--copy-source <value>
[--copy-source-if-match <value>]
[--copy-source-if-modified-since <value>]
[--copy-source-if-none-match <value>]
[--copy-source-if-unmodified-since <value>]
[--expires <value>]
[--grant-full-control <value>]
[--grant-read <value>]
[--grant-read-acp <value>]
[--grant-write-acp <value>]
--key <value>
[--metadata <value>]
[--metadata-directive <value>]
[--tagging-directive <value>]
[--server-side-encryption <value>]
[--storage-class <value>]
[--website-redirect-location <value>]
[--sse-customer-algorithm <value>]
[--sse-customer-key <value>]
[--sse-customer-key-md5 <value>]
[--ssekms-key-id <value>]
[--ssekms-encryption-context <value>]
[--copy-source-sse-customer-algorithm <value>]
[--copy-source-sse-customer-key <value>]
[--copy-source-sse-customer-key-md5 <value>]
[--request-payer <value>]
[--tagging <value>]
[--object-lock-mode <value>]
[--object-lock-retain-until-date <value>]
[--object-lock-legal-hold-status <value>]
[--cli-input-json | --cli-input-yaml]
[--generate-cli-skeleton <value>]
[--cli-auto-prompt <value>]
バケット名、コピー元オブジェクト、コピー先オブジェクトが必須オプションになっています。メタデータを更新 (追加・削除) する場合は、 --cache-control
や --metadata
オプションに加えて --metadata-directive
オブションを使って実行します。
CacheControl の追加
まずはキャッシュに関するメタデータを追加してみます。
$ aws s3api copy-object \
--bucket s3-metadata-test-michimani \
--copy-source s3-metadata-test-michimani/sample.json \
--key sample.json \
--cache-control "public, max-age=31536000" \
--metadata-directive REPLACE
オプションの指定で注意したいのは、 --copy-source
オプションで指定する値には バケット名も含める必要がある 点です。
また、 --metadata-directive
を指定しないと、下記のようなエラーになります。
An error occurred (InvalidRequest) when calling the CopyObject operation: This copy request is illegal because it is trying to copy an object to itself without changing the object’s metadata, storage class, website redirect location or encryption attributes.
--metadata-directive
オプションに対する値は COPY
または REPLACE
を指定します。
--metadata-directive (string)
Specifies whether the metadata is copied from the source object or
replaced with metadata provided in the request.
Possible values:
o COPY
o REPLACE
REPLACE
を指定すると、 copy-object
実行時に指定したメタデータで上書きすることができます。この 上書き には注意が必要なので、これについては後ほど書きます。
では、念のためメタデータが追加できたか確認してみます。
$ aws s3api head-object \
--bucket s3-metadata-test-michimani \
--key sample.json
{
"AcceptRanges": "bytes",
"LastModified": "2020-07-28T22:56:15+00:00",
"ContentLength": 35,
"ETag": "\"6f1d414f6389f754c0a93fab4727f2d9\"",
"CacheControl": "public, max-age=31536000",
"ContentType": "binary/octet-stream",
"Metadata": {}
}
CacheControl
のメタデータが追加されています。
カスタムメタデータを追加する
次に、先程の CacheControl
に 加えて ユーザ独自のカスタムメタデータを追加してみます。カスタムメタデータを追加する場合は、 --metadata
オプションでキーと値を指定します。
今回は、 stage
というキーで dev
という値を持つメタデータを追加してみます。
$ aws s3api copy-object \
--bucket s3-metadata-test-michimani \
--copy-source s3-metadata-test-michimani/sample.json \
--key sample.json \
--metadata stage=dev \
--metadata env=dev,env-name=development
{
"CopyObjectResult": {
"ETag": "\"6f1d414f6389f754c0a93fab4727f2d9\"",
"LastModified": "2020-07-28T23:06:06+00:00"
}
}
確認してみます。
$ aws s3api head-object \
--bucket s3-metadata-test-michimani \
--key sample.json
{
"AcceptRanges": "bytes",
"LastModified": "2020-07-28T23:11:08+00:00",
"ContentLength": 35,
"ETag": "\"6f1d414f6389f754c0a93fab4727f2d9\"",
"ContentType": "binary/octet-stream",
"Metadata": {
"env": "dev",
"env-name": "development"
}
}
カスタムメタデータは正しく追加されましたが、先程追加した CacheControl
が削除されてしまいました。これは --metadata-directive REPLACE
を指定したために元のメタデータを上書きするからです。
元のメタデータを保持したまま別のメタデータを追加する場合には、あらためて元のメタデータも指定する必要があるようです。
$ aws s3api copy-object \
--bucket s3-metadata-test-michimani \
--copy-source s3-metadata-test-michimani/sample.json \
--key sample.json \
--cache-control "public, max-age=31536000" \
--metadata-directive REPLACE \
--metadata env=dev,env-name=development
{
"CopyObjectResult": {
"ETag": "\"6f1d414f6389f754c0a93fab4727f2d9\"",
"LastModified": "2020-07-28T23:23:22+00:00"
}
}
確認してみます。
$ aws s3api head-object \
--bucket s3-metadata-test-michimani \
--key sample.json
{
"AcceptRanges": "bytes",
"LastModified": "2020-07-28T23:23:22+00:00",
"ContentLength": 35,
"ETag": "\"6f1d414f6389f754c0a93fab4727f2d9\"",
"CacheControl": "public, max-age=31536000",
"ContentType": "binary/octet-stream",
"Metadata": {
"env": "dev",
"env-name": "development"
}
}
無事にメタデータを追加することができました。
--metadata
オプションでは、上記のように キー=値
という形式で指定する他、 JSON 形式でも指定できます。
--metadata (map)
A map of metadata to store with the object in S3.
key -> (string)
value -> (string)
Shorthand Syntax:
KeyName1=string,KeyName2=string
JSON Syntax:
{"string": "string"
...}
メタデータの削除
メタデータを削除する場合は、削除したいメタデータを 指定せずに a3api copy-object
コマンドを実行します。
例えば、 カスタムメタデータの stage-name
を削除したい場合、次のように実行します。
$ aws s3api head-object \
--bucket s3-metadata-test-michimani \
--key sample.json
{
"AcceptRanges": "bytes",
"LastModified": "2020-07-28T23:25:14+00:00",
"ContentLength": 35,
"ETag": "\"6f1d414f6389f754c0a93fab4727f2d9\"",
"CacheControl": "public, max-age=31536000",
"ContentType": "binary/octet-stream",
"Metadata": {
"env": "dev"
}
}
削除 というよりは、やはり 上書き という意識で実行するのが良さそうです。
まとめ
AWS CLI を使って Amazon S3 に格納されているオブジェクトのメタデータを変更してみた話でした。
やる前には、 update-metadata
や put-metadata
みたいなコマンドがあってそれを使えばいいと思っていましたが、そうではなかったようです。追加や削除をする場合でも、コピーして 上書きする というのがポイントかなと思いました。
comments powered by Disqus