世の中には設定をJSON形式で与えるソフトウェアがたくさんあります。
GUIで適当に設定できる、あるいはしてもいい場合は適当にやればいいのですが、変更する対象のリソースが大量にある場合、CLIを介して複数同時にオペレーションした方がいい場合もあるでしょう。
その際、与える設定値であるJSONの形式がそこまで複雑ではない場合、CLIの引数に与えるJSONを1行に収めてそのまま与えるでしょう。
たとえばawscliのsecretsmanager tag-resourceコマンドのドキュメントにはこんな例が書いてあります。
aws secretsmanager tag-resource \ --secret-id MyTestSecret \ --tags '[{"Key": "FirstTag", "Value": "FirstValue"}, {"Key": "SecondTag", "Value": "SecondValue"}]'
この場合、引数として与えられているJSONはたかだか要素数が2のリストなので、まだ素直に引数としてそのまま与えればいいと思います。
しかし、これが以下の様になったらもう見づらくてしょうがないと思います。
aws secretsmanager tag-resource \ --secret-id MyTestSecret \ --tags '[{"Key":"id","Value":"$id"},{"Key":"environment","Value":"$environment"},{"Key":"role","Value":"$role"},{"Key":"owner","Value":"$owner"},{"Key":"description","Value":"description"}]'
正直私の目ではもうこの時点で辛いです。
しかも書くのが一回だけでなく、手順書やらドキュメントに残す場合、明らかに読みづらいので何かしら手を打ちたいところです。
何かうまい方法はないものかとChatGPTに聞いてみたら、中々いいなと思った返答が返ってきました。
具体的にはヒアドキュメントを活用して改行とインデントを含むJSON文字列を変数に格納し、それをCLI実行時にブレース展開する形で与えてやればいいという感じです。
具体的には以下の通りです。
tags=$(cat <<EOF [ {"Key": "id", "Value": "$id"}, {"Key": "environment", "Value": "$environment"}, {"Key": "role", "Value": "$role"}, {"Key": "owner", "Value": "$owner"}, {"Key": "description", "Value": "description"} ] EOF ) aws secretsmanager tag-resource \ --secret-id MyTestSecret \ --tags "$tags"
シェルスクリプトとかbashマスターな人には別に当たり前の使い方なのかもしれませんが、私としてはこういう書き方を学んだことも思いついたこともなかったので非常に勉強になりました。
(2024/02/19 追記)
以前に似たような問題で記事にしていたことを書き上げた後に思い出しました。
この時はただ1行に収めるだけのやり方でしたが、今回のやり方の方が応用できるケースが多そうでいいのかな、とは思います。