aws-cliのec2 describe-instancesでいい感じに情報を取得できるquery(JMES-Path)を考えてみる

aws-cliの出力結果をいい感じに整形できる`--query`オプションですが、本記事ではEC2インスタンス情報から一般的？かと思われる情報を出力する`クエリ（JMES-Path）`について考えてみます。

## ec2 describe-instancesで取得できる項目を選択する

[aws ec2 describe-instances / output](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ec2/describe-instances.html#output)

`ec2 describe-instances`コマンドは様々な情報が取得できますが、出力される構造については上記ドキュメントに記載があります。

今回は下記の一覧を出力したかったのでこちらを取得するようなJMES-Pathについて考えます。

- InstanceId
- `Name`タグ
- _Descriptionタグ（任意設定したタグ）
- InstanceType
- AvailabilityZone
- EnaSupport
- Platform
- VirtualizationType
- PIP（PrivateIP)
- Tenancy

これを取得できるように書いてみると下記のようになります。

```powershell
aws ec2 describe-instances --output json --query 'Reservations[].Instances[].{InstanceId:InstanceId,Name:Tags[?Key==`Name`].Value|[0],_Description:Tags[?Key==`_Description`].Value|[0],InstanceType:InstanceType,AvailabilityZone:Placement.AvailabilityZone,EnaSupport:EnaSupport,Platform:Platform,VirtualizationType:VirtualizationType,PIP:NetworkInterfaces[].PrivateIpAddress[]| join(`,`,@),Tenancy:Placement.Tenancy} | sort_by(@, &Name)'
```

##　どんな情報が取得できるか確認します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/0d229f3c-a6d2-69fc-d4f4-e8af21e8a9f6.png)

上記のようにタグ登録されているインスタンスからは下記のような情報が取得できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/dd2ecdc4-d6ad-0dd2-b32f-31468d9a626c.png)

## JMEA-Pathでやってることを分解

```JMES-Path
'Reservations[].Instances[].{InstanceId:InstanceId,Name:Tags[?Key==`Name`].Value|[0],_Description:Tags[?Key==`_Description`].Value|[0],InstanceType:InstanceType,AvailabilityZone:Placement.AvailabilityZone,EnaSupport:EnaSupport,Platform:Platform,VirtualizationType:VirtualizationType,PIP:NetworkInterfaces[].PrivateIpAddress[]| join(`,`,@),Tenancy:Placement.Tenancy} | sort_by(@, &Name)
```

上記ではごちゃごちゃして長いので分解して考えてみます。

- `Reservations[].Instances[]`

`ec2 describe-instance`の情報はReservationsリストの中のInstancesリストに含まれるのでこれを展開します。

### Instancesリストから情報を取得

Instancesリストにある項目を取得

JMES-Pathでは`[項目名1]`といった指定の他に`{別名:項目1}`といった指定ができるので今回はこちらの別名をつけられる方法で指定している。

exsample
`Reservations[].Instances[].{別名1:項目名1,別名2,項目名2}`

下記項目についてはもともとの項目名のまま取得している

- InstanceId:InstanceId
- InstanceType:InstanceType
- EnaSupport:EnaSupport
- Platform:Platform
- VirtualizationType:VirtualizationType

### Tagsリストから情報を取得

Instancesリストの中のTagsリストにタグ情報は格納されている。

今回、標準タグのNameタグと任意登録した`_Description`というタグを出力したかたので下記のようにタグ値をJMES-Pathで展開しててタグ値を取得する。

- `Name:Tags[?Key==`Name`].Value|[0]`

Nameタグは`Instances`の中の`Tags`リストに含まれるので、Key項目のNameでフィルタして取得できたValueをNameという項目名で取得

- `_Description:Tags[?Key==`_Description`].Value|[0]`

任意で登録したタグ`_Description`についても、Tagsリストに含まれるので、Nameタグと同様にKey項目を_DescriptionでフィルタしてValueを`_Description`という項目名で取得

### Placement構造からAvailabilityZoneとTenancyを取得

- `AvailabilityZone:Placement.AvailabilityZone`
- `Tenancy:Placement.Tenancy`

AZとテナンシーはPlacement構造に含まれるため下記のように展開

Placement.項目名　だと長いのでそれぞれ、AvailabilityZone,Tenancyの項目名で取得

### NetworkInterfacesリストからPrivateIPを取得

- `PIP:NetworkInterfaces[].PrivateIpAddress[]| join(`,`,@)`

PrivateIPはNetworkInterfacesのリストに含まれており、NICが複数枚ささっている場合は複数取得できるため、PrivateIPAddressを取得してカンマ区切りでJoinして項目名PIPで取得

## 総評

`--query`オプションをさわりはじめた時は、どうやってタグ情報を出力するの？　だったり色々と疑問がわきますが。

[examples](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ec2/describe-instances.html#examples)

コマンドドキュメントのexamples

`Example 10: To filter instances of the specified type and only display their instance IDs, Availability Zone and the specified tag value in table format`

というそのものズバリがサンプルが用意されていて。

よくある疑問が解消されるよくできたドキュメントだなと感じます。