AWS CLI出力結果をJMESPathでできるだけ見やすくする
西澤です。みんな大好きAWS CLIでは、--query
オプション(JMESPath)を利用して、様々な出力制御を行うことができます。どこまでAWS CLIでやるべきか、という議論は一旦置いておいて、今回試してみたことの一部を簡単にご紹介したいと思います。
JMESPath関連の記事も充実して来ているので、ぜひ他の記事も合わせてご覧ください。
- JMESPath チュートリアル | Developers.IO
- JMESPath チュートリアルでプロジェクションを理解する | Developers.IO
- JMESPathのターミナル探索ツール「jmespath.terminal」 | Developers.IO
AWS CLIの出力結果を見やすくする(基本編)
そのままjsonで出力
まずはそのままjsonで出力します。これを順番に整形していきます。
$ aws ec2 describe-availability-zones \ --region us-west-2 { "AvailabilityZones": [ { "State": "available", "RegionName": "us-west-2", "Messages": [], "ZoneName": "us-west-2a" }, { "State": "available", "RegionName": "us-west-2", "Messages": [], "ZoneName": "us-west-2b" }, { "State": "available", "RegionName": "us-west-2", "Messages": [], "ZoneName": "us-west-2c" } ] }
任意のKeyのみを取り出して表示
この辺りは既にご存知の方が多いと思いますが、一部のKeyのValueのみを取り出して表示することができます。
$ aws ec2 describe-availability-zones \ --region us-west-2 \ --query "AvailabilityZones[].[State,ZoneName]" [ [ "available", "us-west-2a" ], [ "available", "us-west-2b" ], [ "available", "us-west-2c" ] ]
Valueのみの配列では都合が悪い場合は、MultiSelect Hashで連想配列にすることができます。
$ aws ec2 describe-availability-zones \ --region us-west-2 \ --query "AvailabilityZones[].{state:State,name:ZoneName}" [ { "state": "available", "name": "us-west-2a" }, { "state": "available", "name": "us-west-2b" }, { "state": "available", "name": "us-west-2c" } ]
AWS CLIの出力結果を見やすくする(中級編)
そのままjsonで出力
まずはそのままjsonで出力します。これを順番に整形していきます。
$ aws ec2 describe-regions { "Regions": [ { "Endpoint": "ec2.ap-south-1.amazonaws.com", "RegionName": "ap-south-1" }, { "Endpoint": "ec2.eu-west-1.amazonaws.com", "RegionName": "eu-west-1" }, { "Endpoint": "ec2.ap-southeast-1.amazonaws.com", "RegionName": "ap-southeast-1" }, { "Endpoint": "ec2.ap-southeast-2.amazonaws.com", "RegionName": "ap-southeast-2" }, { "Endpoint": "ec2.eu-central-1.amazonaws.com", "RegionName": "eu-central-1" }, { "Endpoint": "ec2.ap-northeast-2.amazonaws.com", "RegionName": "ap-northeast-2" }, { "Endpoint": "ec2.ap-northeast-1.amazonaws.com", "RegionName": "ap-northeast-1" }, { "Endpoint": "ec2.us-east-1.amazonaws.com", "RegionName": "us-east-1" }, { "Endpoint": "ec2.sa-east-1.amazonaws.com", "RegionName": "sa-east-1" }, { "Endpoint": "ec2.us-west-1.amazonaws.com", "RegionName": "us-west-1" }, { "Endpoint": "ec2.us-west-2.amazonaws.com", "RegionName": "us-west-2" } ] }
出力結果をソートする
sort_by
関数を使って結果をソートしたい場合があります。
$ aws ec2 describe-regions \ --query "sort_by(Regions,&RegionName)[].RegionName" [ "ap-northeast-1", "ap-northeast-2", "ap-south-1", "ap-southeast-1", "ap-southeast-2", "eu-central-1", "eu-west-1", "sa-east-1", "us-east-1", "us-west-1", "us-west-2" ]
単一のValueのみなら、sort
関数も使えます。
$ aws ec2 describe-regions --query "sort(Regions[].RegionName)" [ "ap-northeast-1", "ap-northeast-2", "ap-south-1", "ap-southeast-1", "ap-southeast-2", "eu-central-1", "eu-west-1", "sa-east-1", "us-east-1", "us-west-1", "us-west-2" ]
MultiSelect Hashで出力した結果をソートすることも可能です。特に出力したいValueの階層が深い場合等ではこの方法が有効です。
$ aws ec2 describe-regions \ --query "sort_by(Regions[].{A:RegionName,B:Endpoint},&A)[].A" [ "ap-northeast-1", "ap-northeast-2", "ap-south-1", "ap-southeast-1", "ap-southeast-2", "eu-central-1", "eu-west-1", "sa-east-1", "us-east-1", "us-west-1", "us-west-2" ]
パイプで渡した連想配列をソートすることも可能です。前から順番にJMESPathを作って行く場合が多いので、この方が読みやすく、書きやすい場合が多いかもしれません。
$ aws ec2 describe-regions \ --query "Regions[].{A:RegionName,B:Endpoint}|sort_by(@,&A)[].A" [ "ap-northeast-1", "ap-northeast-2", "ap-south-1", "ap-southeast-1", "ap-southeast-2", "eu-central-1", "eu-west-1", "sa-east-1", "us-east-1", "us-west-1", "us-west-2" ]
出力結果を逆順ソートする
reverse
を使えば、出力結果をそっくり逆順に並べ替えることもできます。
$ aws ec2 describe-regions \ --query "reverse(sort_by(Regions,&RegionName)[].RegionName)" [ "us-west-2", "us-west-1", "us-east-1", "sa-east-1", "eu-west-1", "eu-central-1", "ap-southeast-2", "ap-southeast-1", "ap-south-1", "ap-northeast-2", "ap-northeast-1" ]
AWS CLIの出力結果を見やすくする(上級編)
任意の文字列を出力結果に含める
エスケープ処理が面倒なのですが、バックスラッシュ("\")を使えば任意の文字列を出力結果に含めることができます。
$ aws ec2 describe-availability-zones \ --region us-west-2 \ --query "AvailabilityZones[].[RegionName,\`で利用できるAZは\`,ZoneName,\`です\`]" \ --output text us-west-2 で利用できるAZは us-west-2a です us-west-2 で利用できるAZは us-west-2b です us-west-2 で利用できるAZは us-west-2c です
これをjoin
関数を利用することで、こんな形にしてみるのはどうでしょうか?区切り文字を空文字にして、joinしたい文字列を配列で並べればOKです。
$ aws ec2 describe-availability-zones \ --region us-west-2 \ --query "AvailabilityZones[].[join(\`\`,[RegionName,\`で利用できるAZは\`,ZoneName,\`です\`])]" \ --output text us-west-2で利用できるAZはus-west-2aです us-west-2で利用できるAZはus-west-2bです us-west-2で利用できるAZはus-west-2cです
AWSアカウントIDをこんな形でそのまま環境変数に入れられるようにしてみるのも良いかもしれません。応用例は色々と考えられそうです。
$ aws sts get-caller-identity \ --query "join(\`\`,[\`export AWSID=\`,Account])" \ --output text export AWSID=123456789012
CSV出力する
このjoin
関数では区切り文字と配列を指定できますので、CSV出力することもできます。下記例ではRegioNameでソートした結果を、CSVで出力しています。
$ aws ec2 describe-regions \ --query "Regions[].{A:RegionName,B:Endpoint}|sort_by(@,&A)[].[join(\`,\`,[A,B])]" \ --output text ap-northeast-1,ec2.ap-northeast-1.amazonaws.com ap-northeast-2,ec2.ap-northeast-2.amazonaws.com ap-south-1,ec2.ap-south-1.amazonaws.com ap-southeast-1,ec2.ap-southeast-1.amazonaws.com ap-southeast-2,ec2.ap-southeast-2.amazonaws.com eu-central-1,ec2.eu-central-1.amazonaws.com eu-west-1,ec2.eu-west-1.amazonaws.com sa-east-1,ec2.sa-east-1.amazonaws.com us-east-1,ec2.us-east-1.amazonaws.com us-west-1,ec2.us-west-1.amazonaws.com us-west-2,ec2.us-west-2.amazonaws.com
jqの方が簡単というご指摘はもっともです。ちょっと無理が出てきている気もします。
表形式で出力する
join
する配列の先頭と最後に空文字をつけてパイプを区切り文字にすれば、こんな出力もできました。
$ aws ec2 describe-regions \ --query "Regions[].{A:RegionName,B:Endpoint}|sort_by(@,&A)[].[join(\`|\`,[\`\`,A,B,\`\`])]" \ --output text |ap-northeast-1|ec2.ap-northeast-1.amazonaws.com| |ap-northeast-2|ec2.ap-northeast-2.amazonaws.com| |ap-south-1|ec2.ap-south-1.amazonaws.com| |ap-southeast-1|ec2.ap-southeast-1.amazonaws.com| |ap-southeast-2|ec2.ap-southeast-2.amazonaws.com| |eu-central-1|ec2.eu-central-1.amazonaws.com| |eu-west-1|ec2.eu-west-1.amazonaws.com| |sa-east-1|ec2.sa-east-1.amazonaws.com| |us-east-1|ec2.us-east-1.amazonaws.com| |us-west-1|ec2.us-west-1.amazonaws.com| |us-west-2|ec2.us-west-2.amazonaws.com|
まとめ
AWS CLIだけでどこまで出力結果を整形できるか、色々と試してみました。正直ちょっと無理している感も否めませんが、何度も実行して結果を残したいような情報収集の為のスクリプトでは活用できる場面もあるのではないでしょうか?今回は説明をわかりやすくする為に、シンプルなjsonの結果を対象にしていますが、jsonが複雑で階層が深くなっていくと、苦戦が強いられます。その辺りのTipsも時間があるときに改めてまとめたいと思っています。
どこかの誰かのお役に立てば嬉しいです。