aws s3api get-object-taggingのレスポンスにオブジェクトキーが含まれないためjqで頑張ってみた

aws s3api get-object-taggingのjsonレスポンスにオブジェクトキーが含まれないため確認し難く、なんとかスクリプトを作成せずにjsonレスポンスへキーを含めようとやってみました。
2021.02.17

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

はじめに

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レスポンスに肝心なキーが含まれていないために非常に遠回りをするケースもあるかと思いますが、コマンドを少し工夫するだけで手軽になったりします。もしも日常業務等で「もしかしたら…」というものがあった場合、改善の糸口になれれば幸いです。