AWS CLIの整形でqueryを使いたい ~AWS CLIのコマンド出力の制御~

そろそろ、見たい情報だけきちんと整形していきたいね。
2020.09.07

みなさんどうも、AWS CLI好き新卒エンジニアのたいがーです🐯

AWS CLIをご利用の皆さん、出力の制御は何を使っていますか?私は以前までjqコマンドを使っていたのですが、"queryを使いこなしたい"と思い、ブログを書きながら整理していきたいと思います。

今回の目標

AWS CLIの出力をqueryで整形し、出力結果を操り、見たい結果だけを表示する。

実行環境

  • macOS Catalina 10.15.6
  • AWS CLI V2

ちなみに、私は./aws/configでのdefaultの設定でJSON形式で出力されるように設定しています。

[default]
output=json

事前準備

今回はEC2インスタンスを2台起動し、その後インスタンスを一覧で表示させる時に整形します。

まずは、EC2インスタンスを起動します。

AMIをAmazon Linux2、インスタンスタイプをt2.nanoのインスタンスを2個起動しましょう。

今回はSSH接続を行なったりしないためキーペアを指定しませんが、キーペアを指定しない場合、ユーザーが別の方法でログインできるように構成されたAMIを選択しない限り、インスタンスに接続できないのでお気をつけください!

$ aws ec2 run-instances --image-id ami-0053d11f74e9e7f52 --instance-type t3.nano --count 2

EC2インスタンスが2台起動しました。出力を制限していく前に、一度そのまま出力してどのような形式なのかを見てみましょう。

何も制御せずに出力してみる

次に、describe-instancesコマンドを何も制限せずに出力してみます。

$ aws ec2 describe-instances

すると、とても長い出力結果になりました。(2つのインスタンスの情報がとても長かったため、後半部分は省略しています。)

{
    "Reservations": [
        {
            "Groups": [],
            "Instances": [
                {
                    "AmiLaunchIndex": 0,
                    "ImageId": "ami-0053d11f74e9e7f52",
                    "InstanceId": "i-XXXXXXXXXXXXXXXX",
                    "InstanceType": "t3.nano",
                    "LaunchTime": "2020-09-07T04:51:34+00:00",
                    "Monitoring": {
                        "State": "disabled"
                    },
                    "Placement": {
                        "AvailabilityZone": "ap-northeast-1d",
                        "GroupName": "",
                        "Tenancy": "default"
                    },
                    "PrivateDnsName": "ip-XXX-XXX-XXX-XXX.ap-northeast-1.compute.internal",
                    "PrivateIpAddress": "XXX.XXX.XXX.XXX",
                    "ProductCodes": [],
                    "PublicDnsName": "ec2-XXX.XXX.XXX.XXX.ap-northeast-1.compute.amazonaws.com",
                    "PublicIpAddress": "XXX.XXX.XXX.XXX",
                    "State": {
                        "Code": 16,
                        "Name": "running"
                    },
                    "StateTransitionReason": "",
                    "SubnetId": "subnet-XXXXX",
                    "VpcId": "vpc-XXXXXXXXXXXX",
                    "Architecture": "x86_64",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/xvda",
                            "Ebs": {
                                "AttachTime": "2020-09-07T04:51:35+00:00",
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-XXXXXXXXXX"
                            }
                        }
                    ],
                    "ClientToken": "XXXXXXXXXXXXXXXXXX",
                    "EbsOptimized": false,
                    "EnaSupport": true,
                    "Hypervisor": "xen",
                    "NetworkInterfaces": [
                        {
                            "Association": {
                                "IpOwnerId": "amazon",
                                "PublicDnsName": "ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com",
                                "PublicIp": "XXX.XXX.XXX.XXX"
                            },
                            "Attachment": {
                                "AttachTime": "2020-09-07T04:51:34+00:00",
                                "AttachmentId": "eni-attach-XXXXXXXXXX",
                                "DeleteOnTermination": true,
                                "DeviceIndex": 0,
                                "Status": "attached"
                            },
                            "Description": "",
                            "Groups": [
                                {
                                    "GroupName": "default",
                                    "GroupId": "sg-XXXXXXXXXX"
                                }
                            ],
                            "Ipv6Addresses": [],
                            "MacAddress": "XX:XX:XX:XX:XX:XX",
                            "NetworkInterfaceId": "eni-XXXXXXXXXXXXXX",
                            "OwnerId": "621908167678",
                            "PrivateDnsName": "ip-XXX-XXX-XXX-XXX.ap-northeast-1.compute.internal",
                            "PrivateIpAddress": "XXX.XXX.XXX.XXX",
                            "PrivateIpAddresses": [
                                {
                                    "Association": {
                                        "IpOwnerId": "amazon",
                                        "PublicDnsName": "ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com",
                                        "PublicIp": "XXX.XXX.XXX.XXX"
                                    },
                                    "Primary": true,
                                    "PrivateDnsName": "ip-XXX-XXX-XXX-XXX.ap-northeast-1.compute.internal",
                                    "PrivateIpAddress": "XXX.XXX.XXX.XXX"
                                }
                            ],
                            "SourceDestCheck": true,
                            "Status": "in-use",
                            "SubnetId": "subnet-XXXXXXXXXX",
                            "VpcId": "vpc-XXXXXXXXXX",
                            "InterfaceType": "interface"
                        }
                    ],
                    "RootDeviceName": "/dev/xvda",
                    "RootDeviceType": "ebs",
                    "SecurityGroups": [
                        {
                            "GroupName": "default",
                            "GroupId": "sg-XXXXXXXXXXX"
                        }
                    ],
                    "SourceDestCheck": true,
                    "VirtualizationType": "hvm",
                    "CpuOptions": {
                        "CoreCount": 1,
                        "ThreadsPerCore": 2
                    },
                    "CapacityReservationSpecification": {
                        "CapacityReservationPreference": "open"
                    },
                    "HibernationOptions": {
                        "Configured": false
                    },
                    "MetadataOptions": {
                        "State": "applied",
                        "HttpTokens": "optional",
                        "HttpPutResponseHopLimit": 1,
                        "HttpEndpoint": "enabled"
                    }
                },
                {
                    ~~ もう一つのインスタンス情報 ~~
                }
            ]
        }
    ]
}

さて、それではここからが本番です。

出力を制限したい

AWS CLIの出力は--queryと打つことで、出力を制限することができます。

今回はインスタンスの開始、停止、再起動などに使うインスタンスIDを取得しましょう。

先ほどのJSONファイルを見返してみます。インスタンスIDはどこに入っているでしょうか。

{
    "Reservations": [
        {
            "Groups": [],
            "Instances": [
                {
                    ...
                    "InstanceId": "i-XXXXXXXXXXXXXXXX",
   ~ 以下略 ~

"Reservationsの中"にある、"Instancesの中"にインスタンスIDが表示されています。

ここからインスタンスIDだけを表示するには、このように表示します。

$ aws ec2 describe-instances --query "Reservations[*].Instances[*].{Instance:InstanceId}"

すると、このように出力されます。

[
    [
        {
            "Instance": "i-XXXXXXXXXXXXXXXXX"
        },
        {
            "Instance": "i-XXXXXXXXXXXXXXXXX"
        }
    ]
]

次に、インスタンスIDとそのStatusを表示してみます。

$ aws ec2 describe-instances --query 'Reservations[*].Instances[*].[{Instance:InstanceId}, {State:State.Name}]'

すると、このように出力されます。

[
    [
        [
            {
                "Instance": "i-XXXXXXXXXXXXXXXXX"
            },
            {
                "State": "running"
            }
        ],
        [
            {
                "Instance": "i-XXXXXXXXXXXXXXXXX"
            },
            {
                "State": "running"
            }
        ]
    ]
]

見やすく整形していきましょう

みなさんも見たい情報だけを表示させ、操作しやすくしていきましょう!

以上、たいがーでした🐯

参考資料