S3バケットの既存の全オブジェクトに--acl bucket-owner-full-control
を一括付与するやり方の備忘録です。
はじめに
おはよう。@bioerrorlogです。
クロスアカウントのS3間でオブジェクトをコピーするとき、--acl bucket-owner-full-control
を付与せずにそのままアップロードしてしまうと、アップロード先のアカウント側からアクセスできなくなることが知られています。
この問題を事前に回避するには、オブジェクトコピー時に--acl bucket-owner-full-controll
を付与したり、コピー先のS3バケットでObject Ownershipを設定したりする方法が挙げられます。
一方、オブジェクトコピー後にこの問題を解消するには、put-object-acl
コマンドを用いて後からbucket-owner-full-controlを付与する方法があります。
aws s3api put-object-acl --bucket destination_awsexamplebucket --key keyname --acl bucket-owner-full-control
※コマンドはオブジェクトコピー元アカウントの権限で実行する必要があります。
しかし、このコマンドはS3オブジェクト1つに対して実行するものであり、特定ディレクトリやバケット全体を指定することはできません。 そうしたい場合には、ちょっとした工夫が必要になります。
今回はそのような、特定ディレクトリやバケット全体を指定して--acl bucket-owner-full-control
を一括付与するやり方を記します。
既存オブジェクトにbucket-owner-full-controllを一括付与する
結論として、以下のコマンドを実行します。
aws s3 ls s3://target-bucket/ --recursive | awk '{print $4}' | xargs -I KEY aws s3api put-object-acl --bucket target-bucket --key "KEY" --acl bucket-owner-full-control
(コマンドはこちらを参考/改変しています)
※追記: 上記コマンドは、オブジェクトキーに日本語が入っていたり、スペースが入っていたりすると上手く機能しません。
代わりに以下のコマンドの方がお勧めです。
aws s3api list-objects-v2 --bucket target-bucket | jq .Contents[].Key | xargs -I KEY aws s3api put-object-acl --bucket target-bucket --key "KEY" --acl bucket-owner-full-control
これは3つのコマンドをパイプで繋げたものであり、指定したS3バケット/ディレクトリ以下にあるオブジェクト全てにbucket-owner-full-control
を付与しています。
以下、上記コマンドを旧バージョンのものと追記バージョンのものとで、それぞれひとつひとつ見ていきます。
追記バージョンコマンドの解説
aws s3api list-objects-v2 --bucket target-bucket | jq .Contents[].Key | xargs -I KEY aws s3api put-object-acl --bucket target-bucket --key "KEY" --acl bucket-owner-full-control
まず、こちら追記バージョンコマンドの解説をします。
aws s3api list-objects-v2 --bucket target-bucket
まずはこちらlist-objects-v2
コマンドにより、以下のようにバケットのオブジェクトリストを取得します。
$ aws s3api list-objects-v2 --bucket target-bucket { "Contents": [ { "LastModified": "2020-11-02T12:45:17.000Z", "ETag": "\"47bce5c74f589f4867dbd57e9ca9f808\"", "StorageClass": "STANDARD", "Key": "aaa.txt", "Size": 3 }, { "LastModified": "2020-11-02T12:45:17.000Z", "ETag": "\"585cc54d19a29743e94948bf6d3a4592\"", "StorageClass": "STANDARD", "Key": "bbb.txt", "Size": 12 }, { "LastModified": "2020-11-02T12:45:17.000Z", "ETag": "\"9df62e693988eb4e1e1444ece0578579\"", "StorageClass": "STANDARD", "Key": "ccc.txt", "Size": 3 }, { "LastModified": "2020-11-02T12:45:17.000Z", "ETag": "\"47bce5c74f589f4867dbd57e9ca9f808\"", "StorageClass": "STANDARD", "Key": "ddd.txt", "Size": 3 }, { "LastModified": "2020-11-02T12:45:17.000Z", "ETag": "\"585cc54d19a29743e94948bf6d3a4592\"", "StorageClass": "STANDARD", "Key": "eee.txt", "Size": 12 }, { "LastModified": "2020-11-02T12:45:17.000Z", "ETag": "\"9df62e693988eb4e1e1444ece0578579\"", "StorageClass": "STANDARD", "Key": "fff.txt", "Size": 3 } ] }
なお、取得範囲を特定パスに絞りたいときは、--prefix
オプションを使用します。
次に、上記実行結果をjq
コマンドで処理します。
jq .Contents[].Key
jq
は、jsonから値を抽出できるコマンドです。
上記コマンドにより、オブジェクトリストのうちオブジェクトキーを抽出します。
$ aws s3api list-objects-v2 --bucket target-bucket-001 | jq .Contents[].Key "aaa.txt" "bbb.txt" "ccc.txt" "ddd.txt" "eee.txt" "fff.txt"
これでちょうど、オブジェクトキーが出力される形になります。
最後にこの出力を受け取って、以下のコマンドを実行します。
xargs -I KEY aws s3api put-object-acl --bucket target-bucket --key "KEY" --acl bucket-owner-full-control
xargs
コマンドは、標準入力からインプットを受けてコマンドを実行するものです。
-I
オプションに指定した変数(今回の例ではKEY
)を置き換え文字とし、標準入力から受け取ったオブジェクトキー名を後続コマンドaws s3api put-object-acl
の--key
オプションに当てています。
以上この3段階のコマンドを経て、指定したディレクトリ以下にある全オブジェクトに--acl bucket-owner-full-control
を付与さることができます。
旧バージョンコマンドの解説
aws s3 ls s3://target-bucket/ --recursive | awk '{print $4}' | xargs -I KEY aws s3api put-object-acl --bucket target-bucket --key "KEY" --acl bucket-owner-full-control
こちら旧バージョンコマンドの解説も残しておきます。
前述の通り、こちらはオブジェクトキーに日本語が入っていたり、スペースが入っていたりすると上手く機能しないので注意が必要です。
aws s3 ls s3://target-bucket/ --recursive
まずはこのaws s3 ls
コマンドで、指定したS3バケット/ディレクトリ以下にある全オブジェクトを取得します。
このコマンド単体の実行結果は以下のようになります。
$ aws s3 ls s3://target-bucket-001/ --recursive 2020-11-02 12:45:17 3 aaa.txt 2020-11-02 12:45:17 12 bbb.txt 2020-11-02 12:45:17 3 ccc.txt 2020-11-02 12:45:17 3 ddd.txt 2020-11-02 12:45:17 12 eee.txt 2020-11-02 12:45:17 3 fff.txt
次に、上記実行結果がawk
コマンドに渡されます。
awk '{print $4}'
awk
コマンドは、テキストデータをパターンで処理できるコマンドです。
'{print $4}'
を指定することで、4行目を出力させています。
ここまでを合わせると、出力は以下のようになります。
$ aws s3 ls s3://target-bucket-001/ --recursive | awk '{print $4}' aaa.txt bbb.txt ccc.txt ddd.txt eee.txt fff.txt
ちょうどオブジェクトキーが出力される形になります。
最後にこの出力を受け取って、以下のコマンドを実行します。
xargs -I KEY aws s3api put-object-acl --bucket target-bucket --key "KEY" --acl bucket-owner-full-control
xargs
コマンドは、標準入力からインプットを受けてコマンドを実行するものです。
-I
オプションに指定した変数(今回の例ではKEY
)を置き換え文字とし、標準入力から受け取ったオブジェクトキー名を後続コマンドaws s3api put-object-acl
の--key
オプションに当てています。
以上この3段階のコマンドを経て、指定したディレクトリ以下にある全オブジェクトに--acl bucket-owner-full-control
を付与さることができます。
おわりに
S3バケットの既存オブジェクトに、--acl bucket-owner-full-control
を一括付与するやり方の備忘録を書きました。
今回はbucket-owner-full-control
を取り上げましたが、ほかのACL権限設定についても同様のやり方で対処することが出来ます。
また、もちろんBoto3などSDKを用いても同様の処理を書くことができます。
が、一行で済んでしまうこの手軽さは、コマンド良いところだと改めて感じます。
関連記事
S3バケットポリシーとIAMポリシーの関係を、同一アカウント・クロスアカウントそれぞれにおいて整理しました。 www.bioerrorlog.work
AWS CLIのs3 cp
とs3 sync
の違いをまとめました。
www.bioerrorlog.work
Boto3でAssumeRoleするやり方を書きました。
www.bioerrorlog.work
参考
Resolve 403 errors from S3 objects uploaded by other accounts
Require access to S3 objects uploaded from another AWS account
Bucket policy examples - Amazon Simple Storage Service
Controlling ownership of uploaded objects using S3 Object Ownership - Amazon Simple Storage Service