aws s3api get-object-taggingのレスポンスにオブジェクトキーが含まれないためjqで頑張ってみた
はじめに
S3上に保存しているオブジェクトで、付与されているタグを元にライフサイクルルールにて整理する、というやり方はコスト削減にて用いている方も多いかと思われます。
ところが、確認してみると実はタグが付与されていなかったという状況に遭遇しました。タグの付与されないルートが存在したためです。幸いにも処理の実行漏れで、修正にて今後は問題ないものでした。残るは未付与オブジェクトの対処です。
今回は、未付与のオブジェクトには階層毎にまるっとタグを再付与する形にしたため、どの階層にあるオブジェクトにタグが付与されていないのかさえ分かればよしとしました。ただ、タグの確認ができるAPIはオブジェクトのキーが含まれないのが困りどころです。以下、未付与オブジェクトを一覧として収集するまでの過程です。
オブジェクト毎のタグセットを拾い集める
aws s3api get-object-tagging
を利用します。が、レスポンスにはオブジェクトのキーが含まれていないため、正直扱いに困るところです。
% aws s3api list-objects --bucket xxxxxxxxxxxxxxxxxxx --prefix XXXXXXXXXXXXX/ \ | jq -r ".Contents[].Key" \ | xargs -I{} -t aws s3api get-object-tagging --bucket xxxxxxxxxxxxxxxxxxx --key {} aws s3api get-object-tagging --bucket xxxxxxxxxxxxxxxxxxx --key XXXXXXXXXXXXX/c.json { "VersionId": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "TagSet": [] } aws s3api get-object-tagging --bucket xxxxxxxxxxxxxxxxxxx --key XXXXXXXXXXXXX/b.json { "VersionId": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB", "TagSet": [] } aws s3api get-object-tagging --bucket xxxxxxxxxxxxxxxxxxx --key XXXXXXXXXXXXX/a.json { "VersionId": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC", "TagSet": [] }
実行コマンドが挟まれているのは、xargsに-t
のオプションを渡しているためです。
レスポンスにオブジェクトのキーを取り込んでみる
jsonレスポンスに対してjqで要素を追加してみます。ただ、普通にパイプで繋げてもリプレイスが効かないため、sh
によってaws s3api get-object-tagging
からjqによる加工を一まとまりのコマンド群による実行に変更しています。
% aws s3api list-objects --bucket xxxxxxxxxxxxxxxxxxx --prefix XXXXXXXXXXXXX/ \ | jq -r ".Contents[].Key" \ | xargs -I{} sh -c "aws s3api get-object-tagging --bucket xxxxxxxxxxxxxxxxxxx --key {} \ | jq '. |= .+ {\"key\": \"{}\"}'" { "VersionId": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "TagSet": [], "key": "XXXXXXXXXXXXX/c.json" } { "VersionId": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB", "TagSet": [], "key": "XXXXXXXXXXXXX/b.json" } { "VersionId": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC", "TagSet": [], "key": "XXXXXXXXXXXXX/a.json" }
これでタグがついていないキーがわかりやすくなりつつ、データとしても再利用しやすい形になりました。
あとがき
jsonレスポンスに肝心なキーが含まれていないために非常に遠回りをするケースもあるかと思いますが、コマンドを少し工夫するだけで手軽になったりします。もしも日常業務等で「もしかしたら…」というものがあった場合、改善の糸口になれれば幸いです。