When working with AWS CLI's describe-instances
, we often need to extract information from different sections of the JSON response (Reservations, Instances, and Tags) and combine them into a single output record. While separate queries work, they're inefficient for automation scripts.
The solution lies in JMESPath's advanced query capabilities. Here's how to combine multiple fields from different levels of the JSON structure:
aws ec2 describe-instances --instance-ids i-xxxxxxxx --query ' Reservations[*].{ reservation: ReservationId, instance_details: Instances[*].{ instance_id: InstanceId, image_id: ImageId }, tags: Instances[*].Tags[?Key==Name].Value }'
For better readability and script processing, we can flatten the output:
aws ec2 describe-instances --instance-ids i-xxxxxxxx --query ' Reservations[].{ reservation_id: ReservationId, instance_id: Instances[].InstanceId | [0], image_id: Instances[].ImageId | [0], name_tag: Instances[].Tags[?Key==Name].Value | [0] }' --output json
For responses containing multiple instances, we need to adjust our query:
aws ec2 describe-instances --query ' Reservations[].Instances[].{ reservation_id: ReservationId, instance_id: InstanceId, image_id: ImageId, name_tag: Tags[?Key==Name].Value | [0] }' --output table
For import into spreadsheets or other systems:
aws ec2 describe-instances --query ' Reservations[].Instances[].[ ReservationId, InstanceId, ImageId, Tags[?Key==Name].Value | [0] ]' --output text | paste -sd, -
Remember that JMESPath uses zero-based indexing. The | [0]
syntax extracts the first element from arrays. For more complex scenarios, consider using join()
or flatten()
functions.
When working with AWS EC2 instances, we often need to extract data from different sections of the describe-instances output simultaneously. The default JSON structure contains nested elements like Reservations, Instances, and Tags, making it challenging to create consolidated output in a single query.
First, let's examine a simplified version of the describe-instances output structure:
{ "Reservations": [ { "ReservationId": "r-123456789", "Instances": [ { "InstanceId": "i-xxxxxxxx", "ImageId": "ami-xxxxxxxx", "Tags": [ { "Key": "Name", "Value": "Production-Server" } ] } ] } ] }
We can combine all three queries into one using JMESPath's multi-select capabilities:
aws ec2 describe-instances --instance-ids i-xxxxxxxx \ --query 'Reservations[*].{Reservation:ReservationId, \ Instance:Instances[*].[InstanceId,ImageId], \ Tag:Instances[*].Tags[?Key==Name].Value}'
For better readability and processing, we can flatten the output:
aws ec2 describe-instances --instance-ids i-xxxxxxxx \ --query 'Reservations[*].Instances[*].{ReservationId:Reservations[0].ReservationId, \ InstanceId:InstanceId, ImageId:ImageId, \ NameTag:Tags[?Key==Name].Value | [0]}' \ --output table
Here's a complete working example that extracts multiple fields and formats them as CSV:
aws ec2 describe-instances --instance-ids i-xxxxxxxx \ --query 'Reservations[*].Instances[*].join(\t, [ Reservations[0].ReservationId, InstanceId, ImageId, Tags[?Key==Name].Value | [0], State.Name ])' \ --output text
For cases where your query returns multiple instances, modify the approach slightly:
aws ec2 describe-instances \ --query 'Reservations[*].Instances[*].{ ReservationId:Reservations[0].ReservationId, InstanceId:InstanceId, ImageId:ImageId, Name:Tags[?Key==Name].Value | [0], Type:InstanceType }' \ --output json
Combining queries is more efficient than making multiple API calls, especially when dealing with hundreds of instances. The single request approach:
- Reduces API call count
- Minimizes network overhead
- Simplifies error handling