queryオプションを主にaws cliの使い方をメモしておきます。随時更新予定です。
queryオプション
queryオプションはaws cliの結果をフィルタ、整形できるオプションです。書式は jq
とか使ったことあるなら馴染みあるはずJMESPathです。
JMESPath Specification — JMESPath
--query (string) A JMESPath query to use in filtering the response data.
query指定無しだと
例えばAMIの一覧を出す以下のコマンド、人の目にもJSONParser無しのスクリプトにも優しくないです。少し前まではここで jq
の出番だったのですが、今はqueryオプションで対応しています。
$ aws ec2 describe-images --owners self { "Images": [ { "VirtualizationType": "hvm", ... ...
基本の使い方
出力形式を知る
クエリするにはクエリ対象のスキーマを知らないといけません。とりあえずコマンド打って確認するのもいいですが、AWSの公式サイトにも纏まっています。使いたいコマンドのOutput項目を確認します。
ec2 — AWS CLI 1.32.12 Command Reference
例えば上で挙げた aws ec2 describe-images
コマンドなら以下のように出力例と、
{ "Images": [ { "VirtualizationType": "paravirtual", "Name": "My server", "Hypervisor": "xen", "ImageId": "ami-5731123e", "RootDeviceType": "ebs", "State": "available", "BlockDeviceMappings": [ { ... ... }
項目毎の説明も記載されています。
Images -> (list)
Information about one or more images. (structure)
Describes an image. Architecture -> (string)
The architecture of the image. ....
queryを使ってみる
実際に動かしてみます。[]
で囲まれていることからも、上の説明からもわかるように Images
という list
の中に。その Architecture
が連想配列で子要素に入っています。
{ "Images": [ { "VirtualizationType": "hvm", ... ...
上で内容を 連想配列の VirtualizationType
の項目を取ってみます。Images配列の一つ目の項目から VirtualizationType
のキーの値を取得するクエリは 'Images[0].VirtualizationType
となります。
$ aws ec2 describe-images --owners self --query 'Images[0].VirtualizationType' "hvm"
配列の添え字は [0:4]
のような範囲指定から [*]
または []
で全部取得などもできます。
$ aws ec2 describe-images --owners self --query 'Images[0:4].VirtualizationType' [ "hvm", "paravirtual", "hvm", "hvm" ]
[]
の中にワイルドカードや数字の代わりに条件式を入れることもできます。先頭に?
を付けてることで条件式になります。
これで条件式が真の項目に絞って取得することができます。条件式の値は「``」で囲むのがポイント。
$ aws ec2 describe-images --owners self --query 'Images[?VirtualizationType == `paravirtual`]' [ { "VirtualizationType": "paravirtual", ... ...
複数条件でANDやOR取りたい場合は、二つ目の条件前には ?
は不要です。
$ aws ec2 describe-images --owners self --query 'Images[?VirtualizationType == `paravirtual` && Name == `ami-a`]'
連想配列部分をマッピングしなおすことも可能です。後書く関数との連携で使います。
$ aws ec2 describe-images --owners self --query 'Images[*].{v:VirtualizationType,n:Name}' [ { "n": "ami-name1", "v": "hvm" }, { "n": "ami-name2", "v": "paravirtual" }, ... ... ]
関数(Functions)
関数の一覧はこちらのサイトで確認できます。ここでは自分が使ったものメモしていきます。
関数使う際に型を意識して利用する必要があります。よくあるのは引数の型がstringなのに 1234
みたいに入力して怒られるパターンです。 後述のto_stringしたり "1234"
のように "
で囲んで利用します。
number (integers and double-precision floating-point format in JSON) string boolean (true or false) array (an ordered, sequence of values) object (an unordered collection of key value pairs) null
contains
例えば DeleteFlag
というタグを設定したAMIを一覧を取得するとします。このようなクエリでいけます。
aws ec2 describe-images --owners self --query 'Images[?Tags[?Key == `DeleteFlag`]]'
DeleteFalg以外にもFlagがあって Flag
という文字列を含むKeyをタグに設定してあるAMIを取得したい場合、contains
を使うとうまくいきます。
$ aws ec2 describe-images --owners self --query 'Images[?Tags[?contains(Key,`Flag`)]]'
「Proj1」という文字がタグに含まれている一覧ならこんな感じ。
$ aws ec2 describe-images --owners self --query 'Images[*].Tags[?contains(`Proj1`,Value)]'
join
$glue
に指定した文字で配列を結合します。
string join(string $glue, array[string] $stringsarray)
配列を引数に取るのでこんな実行例があります。
インスタンスIDを #
区切りで出力
$ aws ec2 describe-instances --query 'join(`%`,Reservations[].Instances[].InstanceId)'
EC2のインスタンスIDと紐付いている複数のEBSを ,
結合、テーブル形式で出力。
$ aws ec2 describe-instances --query 'Reservations[].Instances[0:10].{ID:InstanceId,EBS:join(`,`,BlockDeviceMappings[].DeviceName)}' --output table -------------------------------------------------------------------------- | DescribeInstances | +------------------------------------------------+-----------------------+ | EBS | ID | +------------------------------------------------+-----------------------+ | /dev/xvda | i-1234abcd | | /dev/sda1,/dev/sdf | i-abcd1234 | | /dev/sda1,/dev/sdf,/dev/sdg,/dev/sdh,/dev/sdi | i-5678efgh | ....
starts_withとends_with
接頭辞と接尾辞判定に使います。
boolean starts_with(string $subject, string $prefix)
boolean ends_with(string $subject, string $suffix)
絞り込みに使うと便利です。
aws ec2 describe-images --owners self --query 'Images[?starts_with(Name,`dev-`)]'
aws ec2 describe-images --owners self --query 'Images[?ends_with(Name,`"20170907"`)]'
to_string
普通のtoStringです。文字列に変換できます。
$ aws ec2 describe-images --owners self --query 'Images[*].BlockDeviceMappings[*].Ebs.VolumeSize' [ [ 80 ], ...
$ aws ec2 describe-images --owners self --query 'Images[*].BlockDeviceMappings[*].Ebs.to_string(VolumeSize)' [ [ "80" ], ...
sort_by
特定のフィールドなどで柔軟にsortします。
sort_by(array elements, expression->number|expression->string expr)
例えばCloudWatchのデータを取ってきたら順番がバラバラでした。
$ aws cloudwatch get-metric-statistics --namespace AWS/EBS --metric-name VolumeQueueLength --period 60 --statistics Average --query 'sort_by(Datapoints[*],&Timestamp)' --output table --start-time 2017-09-01T10:00:00Z --end-time 2017-09-01T10:30:00Z --dimensions Name=VolumeId,Value=vol-abcd1234 -------------------------------------------------------- | GetMetricStatistics | +--------------------+------------------------+--------+ | Average | Timestamp | Unit | +--------------------+------------------------+--------+ | 0.000833333333333 | 2017-09-01T10:00:00Z | Count | | 1.9456 | 2017-09-01T10:05:00Z | Count | | 0.000533333333333 | 2017-09-01T10:20:00Z | Count | | 0.0141 | 2017-09-01T10:25:00Z | Count | | 0.672766666667 | 2017-09-01T10:10:00Z | Count | | 0.000133333333333 | 2017-09-01T10:15:00Z | Count | +--------------------+------------------------+--------+
sort_byでTimestampのフィールドを使ってsortしてみました。
$ aws cloudwatch get-metric-statistics --namespace AWS/EBS --metric-name VolumeQueueLength --period 60 --statistics Average --query 'Datapoints[*]' --output table --start-time 2017-09-01T10:00:00Z --end-time 2017-09-01T10:30:00Z --dimensions Name=VolumeId,Value=vol-abcd1234 -------------------------------------------------------- | GetMetricStatistics | +--------------------+------------------------+--------+ | Average | Timestamp | Unit | +--------------------+------------------------+--------+ | 0.000833333333333 | 2017-09-01T10:00:00Z | Count | | 1.9456 | 2017-09-01T10:05:00Z | Count | | 0.672766666667 | 2017-09-01T10:10:00Z | Count | | 0.000133333333333 | 2017-09-01T10:15:00Z | Count | | 0.000533333333333 | 2017-09-01T10:20:00Z | Count | | 0.0141 | 2017-09-01T10:25:00Z | Count | +--------------------+------------------------+--------+
パイプ使った書き方例はこちら。
$ aws cloudwatch get-metric-statistics --namespace AWS/EBS --metric-name VolumeQueueLength --period 60 --statistics Average --query 'Datapoints[*] | sort_by(@,&Timestamp)' --output table --start-time 2017-09-01T10:00:00Z --end-time 2017-09-01T10:30:00Z --dimensions Name=VolumeId,Value=vol-abcd1234
length
特定の項目の件数(count)を調べたい時はlengthを使います。
$ aws rds describe-db-instances --query 'length(DBInstances[?DBInstanceIdentifier==`your-rds-name`])'
Tips
JMESPATH文法を手軽に試したい
オンラインでJMESPATH試せます。
「EC2のインスタンスID」→「TagのName」を取得
$ aws ec2 describe-tags --query 'Tags[?ResourceId == `i-abcd1234` && Key == `Name`].Value' --output text
「TagのName」→「EC2のインスタンスID」を取得
$ aws ec2 describe-tags --query 'Tags[?ResourceType == `instance` && Key == `Name` && Value == `host_name`].ResourceId' --output text
starts_withやcontainsと一緒に使っても便利です。最後に連想配列にマップすると列で結果を出力できます。
$ aws ec2 describe-tags --query 'Tags[?ResourceType == `instance` && Key == `Name` && starts_with(Value,`dev-`)].{R:ResourceId}' --output text i-abcd1234 i-efgh5678 ...
特定のプロジェクトのインスタンス名一覧(どちらもタグから取得)
aws ec2 describe-instances --query 'Reservations[].Instances[?Tags[?Key == `Project` && Value == `AAAA`]].Tags[][?Key == `Name`].Value' --out text
Athenaでユーザごとのクエリ利用状況を取得したい
ELBを命名規則を元に抽出
命名規則からprefixとsufixを元に抽出。
aws elb describe-load-balancers --query 'LoadBalancerDescriptions[?starts_with(LoadBalancerName,`dev`) && ends_with(LoadBalancerName,`front`)].LoadBalancerName'
EC2とRDSのReserved Instancesの一覧情報
RIの一覧情報
aws ec2 describe-reserved-instances --query 'ReservedInstances[*] | sort_by(@,&Start)[*].{aState:State,bRIID:ReservedInstancesId,cAZ:AvailabilityZone,dType:InstanceType,eCount:InstanceCount,fStart:Start,gEnd:End}' --output table
aws rds describe-reserved-db-instances --query 'ReservedDBInstances[*] | sort_by(@,&StartTime)[*].{aState:State,bReservedDBInstanceId:ReservedDBInstanceId,dMultiAZ:MultiAZ,cDBInstanceClass:DBInstanceClass,eStartTime:StartTime,fProductDescription:ProductDescription}' --output table
関連するAMIのSnapshot一覧
名前が 「 dev-
」始まりのAMIに紐付いたスナップショットの一覧取得
$ aws ec2 describe-images --owners self --query 'Images[?starts_with(Name,`dev-`)].{ID:ImageId,Name:Name,EBS:join(`,`,BlockDeviceMappings[*].Ebs.SnapshotId),VolumeSize:join(`,`,BlockDeviceMappings[*].Ebs.to_string(VolumeSize))}'
CloudFormationのOutput
CloudFormationのスタックデプロイ後にOutputsを取得。
$ aws cloudformation describe-stacks --stack-name your-stack-name --query "Stacks[0].Outputs" --output table -------------------------------------------------------------------------------------------------------------- | DescribeStacks | +---------------------------+------------+-------------------------------------------------------------------+ | Description | OutputKey | OutputValue | +---------------------------+------------+-------------------------------------------------------------------+ | URL of your API endpoint | ApiUrl | https://abcdefg.execute-api.ap-northeast-1.amazonaws.com/dev | +---------------------------+------------+-------------------------------------------------------------------+
IAMのCredential Reportをデコードして出力
IAMの認証情報レポートを見る方法。
AWS アカウント の認証情報レポートの取得 - AWS Identity and Access Management
# IAMのレポート出力を開始 $ aws iam generate-credential-report { "State": "STARTED", "Description": "No report exists. Starting a new report generation task" } # IAMのレポート出力が完了 $ aws iam generate-credential-report { "State": "COMPLETE" } # レポートはBase64でエンコードされている $ aws iam get-credential-report { "Content": "BASE64encoded.....xOL0E=", "ReportFormat": "text/csv", "GeneratedTime": "2019-02-02T00:14:13Z" } # base64コマンドでデコード $ aws iam get-credential-report --query 'Content' --output text | base64 -d user,arn,user_creation_time,password_enabled,password_last_used,password_last_changed,password_next_rotation,mfa_active,access_key_1_active,access_key_1_last_rotated,access_key_1_last_used_date,access_key_1_last_used_region,access_key_1_last_used_service,access_key_2_active,access_key_2_last_rotated,access_key_2_last_used_date,access_key_2_last_used_region,access_key_2_last_used_service,cert_1_active,cert_1_last_rotated,cert_2_active,cert_2_last_rotated <root_account>,arn:aws:iamーーー以下省略
EC2のコンソール画面
EC2のコンソール画面はAWSコンソールから結構面倒ですし、grep等の処理するにも面倒ですがコマンドで取得できます。
コマンドラインでEC2のコンソール画面テキスト(システムログ)を取得してgrep分析 - YOMON8.NET
EC2で自身が所属しているVPC IDの取得
$ vpcid=$(aws ec2 describe-instances --query "Reservations[].Instances[?InstanceId == \`$(curl -s 169.254.169.254/2021-01-03/meta-data/instance-id)\`].VpcId" --output text) $ echo $vpcid vpc-xxxxx
Bashとの連携
通常の出力でもJSONのパーサーとかあれば使えます。でもBashとの連携となると少し加工した方が使いやすいです。
$ aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId' [ "i-abcd1234", "i-efgf5678", "i-ijklmn9", ....
--output text
を付けるとタブ区切りで出力されます。これでも結構使えます。
$ aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId' --output text i-abcd1234 i-efgh5678 i-ijklmn9...
更に少し工夫してダミーの連想配列マップしてからtext形式で出力とやると縦に並びます。これで連携しやすうなりまs。
$ aws ec2 describe-instances --query 'Reservations[].Instances[].{i:InstanceId}' --output text i-abcd1234 i-efgh5678 i-ijklmn9 ...
Debug
Debugオプションあるので動きを詳しく追いたい場合は使えます。結果はエラー出力に出てきます。
aws ec2 describe-tags --debug 2> debuglog.txt
TagのNameがXXXから始まるSubnet一覧
aws ec2 describe-subnets --query 'Subnets[?Tags[?Key == `Name` && starts_with(Value,`Common`)]]'