AWS CLIにおける–queryの使い方・書き方・記述例

4月 21, 2017AWS,AWS CLI

AWSサービスのリソースをコマンドやプログラムから使用するために用意されているものがAWS CLIや各プログラム言語のAWS SDKになります。
特にAWS CLIはMac OSXやLinuxなどのシェルスクリプトから実行するもののため、Unixベースの開発を行なっている場合にはAWSの操作をコーディングするのに強力なツールとなります。

ただ、AWS CLIのドキュメントは英語であり中でも–queryというAWS CLIの実行結果の表示形式を指定したり、条件を与えて検索結果を絞り込んだりする機能はAWS CLIを初めて使用した際には解りづらい部分もあります。
そこで今回はAWS CLIの–queryを表示形式を指定する機能について書き方・記述例を備忘録として記載したいと思います。

なお、後述しますがAWS CLIには–filtersという機能で検索条件を指定して結果を絞り込む機能がありますが、–queryにも同様のことができる機能があります。
この点については今回は記載せず、別の機会に説明したいと思います。

AWS CLIにおける–queryの使い方・書き方・記述例

AWS CLIの–queryに指定するクエリパラメタの書き方・記述方法の例を記載します。
まず–queryで検索結果の表示形式を指定して必要な要素を表示するために重要になるのが、検索結果の返却値の構造になります。
検索結果の返却値の構造は各AWS CLIコマンドリファレンスの「Output」という項目部分に記載されています。

AWS CLIコマンドリファレンス
https://docs.aws.amazon.com/cli/latest/

「describe-images」のAWS CLIコマンドリファレンス
https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-images.html

今回はAWS CLIのうち比較的要素の項目が少なく構造がわかりやすいdescribe-imagesで各アカウントで共通で使用出来るAmazon LinuxのAMIを検索対象にして–queryの記述例を記載したいと思います。

AWS CLIの検索結果が1件の場合の例

まずはAMIを1件のみ指定して–queryの例を示したいと思います。
以下の説明で使用するAMI: ami-383c1956(Amazon Linux AMI 2015.09.1 x86_64 HVM GP2)

–queryを使用せず検索結果をそのまま表示する例

AWS CLIコマンドリファレンスの「Output」の構造説明でわかりにくい場合は検索結果が1件になるようにして、このように実際に検索して具体的な構造を把握することも可能です。

[magtranetwork@localhost ~]$ aws ec2 describe-images --image-id ami-383c1956 --output json
{
    "Images": [
        {
            "VirtualizationType": "hvm", 
            "Name": "amzn-ami-hvm-2015.09.1.x86_64-gp2", 
            "Hypervisor": "xen", 
            "ImageOwnerAlias": "amazon", 
            "SriovNetSupport": "simple", 
            "ImageId": "ami-383c1956", 
            "State": "available", 
            "BlockDeviceMappings": [
                {
                    "DeviceName": "/dev/xvda", 
                    "Ebs": {
                        "DeleteOnTermination": true, 
                        "SnapshotId": "snap-09677294", 
                        "VolumeSize": 8, 
                        "VolumeType": "gp2", 
                        "Encrypted": false
                    }
                }
            ], 
            "Architecture": "x86_64", 
            "ImageLocation": "amazon/amzn-ami-hvm-2015.09.1.x86_64-gp2", 
            "RootDeviceType": "ebs", 
            "OwnerId": "137112412989", 
            "RootDeviceName": "/dev/xvda", 
            "CreationDate": "2015-10-29T18:13:04.000Z", 
            "Public": true, 
            "ImageType": "machine", 
            "Description": "Amazon Linux AMI 2015.09.1 x86_64 HVM GP2"
        }
    ]
}

JSON配列「Images」の内容を表示する例。

上記のJSON構造のようにImagesは配列内に要素を持つ形なのでImagesの内容を表示するにはImages[]と[]をつけて配列型で示す必要があります。

[magtranetwork@localhost ~]$ aws ec2 describe-images --image-id ami-383c1956 --output json --query 'Images[]'
[
    {
        "VirtualizationType": "hvm", 
        "Name": "amzn-ami-hvm-2015.09.1.x86_64-gp2", 
        "Hypervisor": "xen", 
        "ImageOwnerAlias": "amazon", 
        "SriovNetSupport": "simple", 
        "ImageId": "ami-383c1956", 
        "State": "available", 
        "BlockDeviceMappings": [
            {
                "DeviceName": "/dev/xvda", 
                "Ebs": {
                    "DeleteOnTermination": true, 
                    "SnapshotId": "snap-09677294", 
                    "VolumeSize": 8, 
                    "VolumeType": "gp2", 
                    "Encrypted": false
                }
            }
        ], 
        "Architecture": "x86_64", 
        "ImageLocation": "amazon/amzn-ami-hvm-2015.09.1.x86_64-gp2", 
        "RootDeviceType": "ebs", 
        "OwnerId": "137112412989", 
        "RootDeviceName": "/dev/xvda", 
        "CreationDate": "2015-10-29T18:13:04.000Z", 
        "Public": true, 
        "ImageType": "machine", 
        "Description": "Amazon Linux AMI 2015.09.1 x86_64 HVM GP2"
    }
]

JSON配列「Images」の内容の単一要素(Nameのみ)を表示する例

上記のJSON構造のようにImagesの内容はBlockDeviceMappings以外配列構造ではないので項目名を指定することで表示できます。
Images配列内のName項目を表示するにはImages[].Nameと指定します。

[magtranetwork@localhost ~]$ aws ec2 describe-images --image-id ami-383c1956 --output json --query 'Images[].Name'
[
    "amzn-ami-hvm-2015.09.1.x86_64-gp2"
]

JSON配列「Images」の内容の単一要素(Nameのみ)をキー名「AMI Name」をつけて表示する例

上記のJSONで出力されるName項目にキー名を与えるにはImages[].{“AMI Name": Name}のように指定します。

[magtranetwork@localhost ~]$ aws ec2 describe-images --image-id ami-383c1956 --output json --query 'Images[].{"AMI Name": Name}'
[
    {
        "AMI Name": "amzn-ami-hvm-2015.09.1.x86_64-gp2"
    }
]

JSON配列「Images」にキー名「AMI」をつけて内容の単一要素(Nameのみ)をキー名「AMI Name」をつけて表示する例

Images配列にキー名を与えるには{“AMI": Images[].{“AMI Name": Name}}のように指定します。

[magtranetwork@localhost ~]$ aws ec2 describe-images --image-id ami-383c1956 --output json --query '{"AMI": Images[].{"AMI Name": Name}}'
{
    "AMI": [
        {
            "AMI Name": "amzn-ami-hvm-2015.09.1.x86_64-gp2"
        }
    ]
}

JSON配列「Images」の先頭要素(0番目)にキー名「AMI」をつけて内容の単一要素(Nameのみ)をキー名「AMI Name」をつけて表示する例

今回の例の場合Images配列の要素は1個で、Imagesの配列要素を1つのみ取り出して配列構造ではない表記にすることもできます。
そのためにはImages[0]のように配列の要素を指定します。

[magtranetwork@localhost ~]$ aws ec2 describe-images --image-id ami-383c1956 --output json --query '{"AMI": Images[0].{"AMI Name": Name}}'
{
    "AMI": {
        "AMI Name": "amzn-ami-hvm-2015.09.1.x86_64-gp2"
    }
}

JSON配列「Images」の先頭要素(0番目)の内容の単一要素(Nameのみ)をキー名「AMI Name」をつけて表示する例

Imagesの配列要素を1つのみ取り出して配列構造ではない表記にし、Name項目にキー名をつけて出力します。

[magtranetwork@localhost ~]$ aws ec2 describe-images --image-id ami-383c1956 --output json --query '{"AMI Name": Images[0].Name}'
{
    "AMI Name": "amzn-ami-hvm-2015.09.1.x86_64-gp2"
}

続いてはImages配列内のName項目に加えてImageIdという項目を表示する例を記載していきますが、基本的には上記で説明したNameのみの項目の表示と同様です。

JSON配列「Images」の内容の複数要素(ImageId、Name)を表示する例

[magtranetwork@localhost ~]$ aws ec2 describe-images --image-id ami-383c1956 --output json --query 'Images[].[ImageId,Name]'
[
    [
        "ami-383c1956", 
        "amzn-ami-hvm-2015.09.1.x86_64-gp2"
    ]
]

JSON配列「Images」の内容の複数要素(ImageId、Name)にそれぞれキー名「AMI ID」「AMI Name」をつけて表示する例

[magtranetwork@localhost ~]$ aws ec2 describe-images --image-id ami-383c1956 --output json --query 'Images[].{"AMI ID": ImageId,"AMI Name": Name}'
[
    {
        "AMI Name": "amzn-ami-hvm-2015.09.1.x86_64-gp2", 
        "AMI ID": "ami-383c1956"
    }
]

JSON配列「Images」にキー名「AMI」をつけて内容の複数要素(ImageId、Name)にそれぞれキー名「AMI ID」「AMI Name」をつけて表示する例

[magtranetwork@localhost ~]$ aws ec2 describe-images --image-id ami-383c1956 --output json --query '{"AMI": Images[].{"AMI ID": ImageId,"AMI Name": Name}}'
{
    "AMI": [
        {
            "AMI Name": "amzn-ami-hvm-2015.09.1.x86_64-gp2", 
            "AMI ID": "ami-383c1956"
        }
    ]
}

JSON配列「Images」の先頭要素(0番目)にキー名「AMI」をつけて内容の複数要素(ImageId、Name)にそれぞれキー名「AMI ID」「AMI Name」をつけて表示する例

[magtranetwork@localhost ~]$ aws ec2 describe-images --image-id ami-383c1956 --output json --query '{"AMI": Images[0].{"AMI ID": ImageId,"AMI Name": Name}}'
{
    "AMI": {
        "AMI Name": "amzn-ami-hvm-2015.09.1.x86_64-gp2", 
        "AMI ID": "ami-383c1956"
    }
}

JSON配列「Images」の先頭要素(0番目)の内容の複数要素(ImageId、Name)にそれぞれキー名「AMI ID」「AMI Name」をつけて表示する例

[magtranetwork@localhost ~]$ aws ec2 describe-images --image-id ami-383c1956 --output json --query '{"AMI ID": Images[0].ImageId,"AMI Name": Images[0].Name}'
{
    "AMI Name": "amzn-ami-hvm-2015.09.1.x86_64-gp2", 
    "AMI ID": "ami-383c1956"
}

AWS CLIの検索結果が複数の場合の例

続いてはJSON配列「Images」に複数要素が入っている例の–queryの記述例を見ていきたいと思います。
またJSON配列「Images」内に入れ子になっているJSON配列「BlockDeviceMappings」の表示の仕方についても記述例を記載しました。

要素をわかりやすくするために今回は–filtersの機能を使用して検索結果を2件に絞り込んでいます。–filtersの記述方法については別途記載する機会を作りたいと思いますが、基本的にはNameに検索する対象の項目名、Valuesに検索条件を記入して検索します。
余談ですが、–queryでも–filtersと同じように検索条件を指定して検索結果を絞り込む機能もあるのですが、今回は検索結果の表示形式の部分に特化して説明しています。

項目名については–queryで使用する返却結果の構造と同様にCLIのリファレンスの「–filters」の部分に記載されています。
https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-images.html

以下の説明で使用する–filtersの条件: 「Amazon*Linux*2015*」 → ami-be728fbe(Amazon Linux AMI 2015.03 (PV) – by VisualOps)、ami-d0728fd0(Amazon Linux AMI 2015.03 (HVM) – by VisualOps)

–queryを使用せず結果をJSON形式でそのまま表示

[magtranetwork@localhost ~]$ aws ec2 describe-images --filters "Name=name,Values=Amazon*Linux*2015*" --output json
{
    "Images": [
        {
            "VirtualizationType": "paravirtual", 
            "Name": "Amazon Linux AMI 2015.03 (PV) - by VisualOps", 
            "Hypervisor": "xen", 
            "ImageId": "ami-be728fbe", 
            "RootDeviceType": "ebs", 
            "State": "available", 
            "BlockDeviceMappings": [
                {
                    "DeviceName": "/dev/sda1", 
                    "Ebs": {
                        "DeleteOnTermination": true, 
                        "SnapshotId": "snap-399521a2", 
                        "VolumeSize": 8, 
                        "VolumeType": "gp2", 
                        "Encrypted": false
                    }
                }
            ], 
            "Architecture": "x86_64", 
            "ImageLocation": "575264825971/Amazon Linux AMI 2015.03 (PV) - by VisualOps", 
            "KernelId": "aki-176bf516", 
            "OwnerId": "575264825971", 
            "RootDeviceName": "/dev/sda1", 
            "CreationDate": "2015-04-01T03:10:07.000Z", 
            "Public": true, 
            "ImageType": "machine", 
            "Description": "The Amazon Linux AMI is an EBS-backed, AWS-supported image. The default image includes AWS command line tools, Python, Ruby, Perl, and Java. The repositories include Docker, PHP, MySQL, PostgreSQL, other packages and VisualOps OpsAgent."
        }, 
        {
            "VirtualizationType": "hvm", 
            "Name": "Amazon Linux AMI 2015.03 (HVM) - by VisualOps", 
            "Hypervisor": "xen", 
            "SriovNetSupport": "simple", 
            "ImageId": "ami-d0728fd0", 
            "State": "available", 
            "BlockDeviceMappings": [
                {
                    "DeviceName": "/dev/xvda", 
                    "Ebs": {
                        "DeleteOnTermination": true, 
                        "SnapshotId": "snap-df962244", 
                        "VolumeSize": 8, 
                        "VolumeType": "gp2", 
                        "Encrypted": false
                    }
                }
            ], 
            "Architecture": "x86_64", 
            "ImageLocation": "575264825971/Amazon Linux AMI 2015.03 (HVM) - by VisualOps", 
            "RootDeviceType": "ebs", 
            "OwnerId": "575264825971", 
            "RootDeviceName": "/dev/xvda", 
            "CreationDate": "2015-04-01T03:14:18.000Z", 
            "Public": true, 
            "ImageType": "machine", 
            "Description": "The Amazon Linux AMI is an EBS-backed, AWS-supported image. The default image includes AWS command line tools, Python, Ruby, Perl, and Java. The repositories include Docker, PHP, MySQL, PostgreSQL, other packages and VisualOps OpsAgent."
        }
    ]
}

JSON配列「Images」にキー名「AMI」をつけて内容の複数要素(ImageId、Name)にそれぞれキー名「AMI ID」「AMI Name」をつけて表示する例

[magtranetwork@localhost ~]$ aws ec2 describe-images --filters "Name=name,Values=Amazon*Linux*2015*" --output json --query '{"AMI": Images[].{"AMI ID": ImageId,"AMI Name": Name}}'
{
    "AMI": [
        {
            "AMI Name": "Amazon Linux AMI 2015.03 (PV) - by VisualOps", 
            "AMI ID": "ami-be728fbe"
        }, 
        {
            "AMI Name": "Amazon Linux AMI 2015.03 (HVM) - by VisualOps", 
            "AMI ID": "ami-d0728fd0"
        }
    ]
}

JSON配列「Images」にキー名「AMI」をつけて内容の複数要素(ImageId、Name、BlockDeviceMappings)にそれぞれキー名「AMI ID」「AMI Name」「EBS」をつけて表示する例

JSON配列「Images」に入れ子で入っているJSON配列「BlockDeviceMappings」の内容はそのまま表示。

[magtranetwork@localhost ~]$ aws ec2 describe-images --filters "Name=name,Values=Amazon*Linux*2015*" --output json --query '{"AMI": Images[].{"AMI ID": ImageId,"AMI Name": Name,"EBS": BlockDeviceMappings[]}}'
{
    "AMI": [
        {
            "AMI Name": "Amazon Linux AMI 2015.03 (PV) - by VisualOps", 
            "AMI ID": "ami-be728fbe", 
            "EBS": [
                {
                    "DeviceName": "/dev/sda1", 
                    "Ebs": {
                        "DeleteOnTermination": true, 
                        "SnapshotId": "snap-399521a2", 
                        "VolumeSize": 8, 
                        "VolumeType": "gp2", 
                        "Encrypted": false
                    }
                }
            ]
        }, 
        {
            "AMI Name": "Amazon Linux AMI 2015.03 (HVM) - by VisualOps", 
            "AMI ID": "ami-d0728fd0", 
            "EBS": [
                {
                    "DeviceName": "/dev/xvda", 
                    "Ebs": {
                        "DeleteOnTermination": true, 
                        "SnapshotId": "snap-df962244", 
                        "VolumeSize": 8, 
                        "VolumeType": "gp2", 
                        "Encrypted": false
                    }
                }
            ]
        }
    ]
}

JSON配列「Images」にキー名「AMI」をつけて内容の複数要素(ImageId、Name、BlockDeviceMappings)にそれぞれキー名「AMI ID」「AMI Name」「EBS」をつけて表示する例

JSON配列「Images」に入れ子で入っているJSON配列「BlockDeviceMappings」の内容は複数要素(VolumeType、VolumeSize)にそれぞれキー名「VolType」「VolSize」をつけて表示。

[magtranetwork@localhost ~]$ aws ec2 describe-images --filters "Name=name,Values=Amazon*Linux*2015*" --output json --query '{"AMI": Images[].{"AMI ID": ImageId,"AMI Name": Name,"EBS": BlockDeviceMappings[].Ebs.{"VolType":VolumeType,"VolSize":VolumeSize}}}'
{
    "AMI": [
        {
            "AMI Name": "Amazon Linux AMI 2015.03 (PV) - by VisualOps", 
            "AMI ID": "ami-be728fbe", 
            "EBS": [
                {
                    "VolType": "gp2", 
                    "VolSize": 8
                }
            ]
        }, 
        {
            "AMI Name": "Amazon Linux AMI 2015.03 (HVM) - by VisualOps", 
            "AMI ID": "ami-d0728fd0", 
            "EBS": [
                {
                    "VolType": "gp2", 
                    "VolSize": 8
                }
            ]
        }
    ]
}

JSON配列「Images」にキー名「AMI」をつけて内容の複数要素(ImageId、Name、BlockDeviceMappings[].Ebs.VolumeType、BlockDeviceMappings[].Ebs.VolumeSize)にそれぞれキー名「AMI ID」「AMI Name」「VolType」「VolSize」をつけて表示する例

JSON配列「Images」に入れ子で入っているJSON配列「BlockDeviceMappings」は上記のBlockDeviceMappings[].Ebs.VolumeType、BlockDeviceMappings[].Ebs.VolumeSizeように「AMI ID」「AMI Name」と同じ階層に直接呼び出す。

[magtranetwork@localhost ~]$ aws ec2 describe-images --filters "Name=name,Values=Amazon*Linux*2015*" --output json --query '{"AMI": Images[].{"AMI ID": ImageId,"AMI Name": Name,"VolType": BlockDeviceMappings[].Ebs.VolumeType,"VolSize": BlockDeviceMappings[].Ebs.VolumeSize}}'
{
    "AMI": [
        {
            "AMI Name": "Amazon Linux AMI 2015.03 (PV) - by VisualOps", 
            "VolType": [
                "gp2"
            ], 
            "AMI ID": "ami-be728fbe", 
            "VolSize": [
                8
            ]
        }, 
        {
            "AMI Name": "Amazon Linux AMI 2015.03 (HVM) - by VisualOps", 
            "VolType": [
                "gp2"
            ], 
            "AMI ID": "ami-d0728fd0", 
            "VolSize": [
                8
            ]
        }
    ]
}

JSON配列「Images」にキー名「AMI」をつけて内容の複数要素(ImageId、Name、BlockDeviceMappings[].Ebs.VolumeType、BlockDeviceMappings[].Ebs.VolumeSize)にそれぞれキー名「AMI ID」「AMI Name」「VolType」「VolSize」をつけて表示する例

JSON配列「Images」に入れ子で入っているJSON配列「BlockDeviceMappings」の先頭要素(0番目)の内容をBlockDeviceMappings[].Ebs.VolumeType、BlockDeviceMappings[].Ebs.VolumeSizeように「AMI ID」「AMI Name」と同じ階層に直接呼び出す。

[magtranetwork@localhost ~]$ aws ec2 describe-images --filters "Name=name,Values=Amazon*Linux*2015*" --output json --query '{"AMI": Images[].{"AMI ID": ImageId,"AMI Name": Name,"VolType": BlockDeviceMappings[0].Ebs.VolumeType,"VolSize": BlockDeviceMappings[0].Ebs.VolumeSize}}'
{
    "AMI": [
        {
            "AMI Name": "Amazon Linux AMI 2015.03 (PV) - by VisualOps", 
            "VolType": "gp2", 
            "AMI ID": "ami-be728fbe", 
            "VolSize": 8
        }, 
        {
            "AMI Name": "Amazon Linux AMI 2015.03 (HVM) - by VisualOps", 
            "VolType": "gp2", 
            "AMI ID": "ami-d0728fd0", 
            "VolSize": 8
        }
    ]
}
Reference: Tech Blog citing related sources